Exemple #1
0
job *job_alloc(void)

  {
  job *pj;

  pj = (job *)calloc(1, sizeof(job));

  if (pj == NULL)
    {
    log_err(errno, "job_alloc", (char *)"no memory");

    return(NULL);
    }

  pj->ji_qs.qs_version = PBS_QS_VERSION;

  CLEAR_LINK(pj->ji_alljobs);
  CLEAR_LINK(pj->ji_jobque);

  CLEAR_HEAD(pj->ji_tasks);
  pj->ji_taskid = TM_NULL_TASK + 1;
  pj->ji_obit = TM_NULL_EVENT;
  pj->ji_nodekill = TM_ERROR_NODE;

  pj->ji_momhandle = -1;  /* mark mom connection invalid */

  /* set the working attributes to "unspecified" */
  job_init_wattr(pj);

  return(pj);
  }  /* END job_alloc() */
Exemple #2
0
struct batch_request *alloc_br(

        int type)

  {

  struct batch_request *req = NULL;

  req = (struct batch_request *)malloc(sizeof(struct batch_request));

  if (req == NULL)
    {
    log_err(errno, "alloc_br", msg_err_malloc);

    return(NULL);
    }

  memset((void *)req, (int)0, sizeof(struct batch_request));

  req->rq_type = type;

  CLEAR_LINK(req->rq_link);

  req->rq_conn = -1;  /* indicate not connected */
  req->rq_orgconn = -1;  /* indicate not connected */
  req->rq_time = time_now;
  req->rq_reply.brp_choice = BATCH_REPLY_CHOICE_NULL;
  req->rq_noreply = FALSE;  /* indicate reply is needed */

  append_link(&svr_requests, &req->rq_link, req);

  return(req);
  }
struct batch_request *alloc_br(int type)
  {
  struct batch_request *req = NULL;

  if (alloc_br_success == false)
    return(NULL);

  req = (struct batch_request *)calloc(1, sizeof(struct batch_request));

  if (req == NULL)
    {
    return(NULL);
    }

  req->rq_type = type;

  req->rq_conn = -1;  /* indicate not connected */
  req->rq_orgconn = -1;  /* indicate not connected */
  req->rq_time = 9877665;
  req->rq_reply.brp_choice = BATCH_REPLY_CHOICE_NULL;
  req->rq_noreply = FALSE;  /* indicate reply is needed */

  CLEAR_LINK(req->rq_link);

  return(req);
  }
Exemple #4
0
/**
 * @brief
 * 		status_sched - Build the status reply for single scheduler
 *
 * @param[in]	psched	-	ptr to sched receiving status query
 * @param[in]	preq	-	ptr to the decoded request
 * @param[out]	pstathd	-	head of list to append status to
 *
 * @return	int
 * @retval	0	: success
 * @retval	!0	: PBSE error code
 */
static int
status_sched(pbs_sched *psched, struct batch_request *preq, pbs_list_head *pstathd)
{
	int		   rc = 0;
	struct brp_status *pstat;
	svrattrl	  *pal;

	pstat = (struct brp_status *)malloc(sizeof(struct brp_status));
	if (pstat == NULL)
		return (PBSE_SYSTEM);

	pstat->brp_objtype = MGR_OBJ_SCHED;
	(void)strncpy(pstat->brp_objname, psched->sc_name, (PBS_MAXSVRJOBID > PBS_MAXDEST ?
			PBS_MAXSVRJOBID : PBS_MAXDEST) -1);
	pstat->brp_objname[(PBS_MAXSVRJOBID > PBS_MAXDEST ? PBS_MAXSVRJOBID : PBS_MAXDEST) - 1] = '\0';

	CLEAR_LINK(pstat->brp_stlink);
	CLEAR_HEAD(pstat->brp_attr);
	append_link(pstathd, &pstat->brp_stlink, pstat);


	bad = 0;
	pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);
	if (status_attrib(pal, sched_attr_def, psched->sch_attr, SCHED_ATR_LAST,
		preq->rq_perm, &pstat->brp_attr, &bad))
		reply_badattr(PBSE_NOATTR, bad, pal, preq);

	return (rc);
}
Exemple #5
0
svrattrl *fill_svrattr_info(

  const char *aname,    /* I */ /* attribute name */
  const char *avalue,   /* I */ /* attribute value */
  const char *rname,   /* i */ /* resource name */
  char       *log_buf,  /* O */ /* error buffer */
  size_t      buf_len)  /* I */ /* len of error buffer */

  {
  size_t vsize = 0;
  svrattrl *pal = NULL;

  if (avalue)
    vsize = strlen(avalue) + 1;

  if ((pal = attrlist_create(aname, rname, vsize)))
    {
    if (avalue) 
      strcpy(pal->al_value, avalue);
    CLEAR_LINK(pal->al_link);
    }
  else
    snprintf(log_buf, buf_len, "Error: could not allocate memory for svrattrl in %s", __func__);

  return pal;
  }
Exemple #6
0
int status_job(

  job                  *pjob,    /* ptr to job to status */
  struct batch_request *preq,
  svrattrl             *pal,     /* specific attributes to status */
  tlist_head           *pstathd, /* RETURN: head of list to append status to */
  int                  *bad)     /* RETURN: index of first bad pbs_attribute */

  {
  struct brp_status *pstat;
  int                IsOwner = 0;
  long               query_others = 0;

  /* see if the client is authorized to status this job */
  if (svr_authorize_jobreq(preq, pjob) == 0)
    IsOwner = 1;

  get_svr_attr_l(SRV_ATR_query_others, &query_others);
  if (!query_others)
    {
    if (IsOwner == 0)
      {
      return(PBSE_PERM);
      }
    }

  /* allocate reply structure and fill in header portion */
  if ((pstat = calloc(1, sizeof(struct brp_status))) == NULL)
    {
    return(PBSE_SYSTEM);
    }

  CLEAR_LINK(pstat->brp_stlink);

  pstat->brp_objtype = MGR_OBJ_JOB;

  strcpy(pstat->brp_objname, pjob->ji_qs.ji_jobid);

  CLEAR_HEAD(pstat->brp_attr);

  append_link(pstathd, &pstat->brp_stlink, pstat);

  /* add attributes to the status reply */
  *bad = 0;

  if (status_attrib(
        pal,
        job_attr_def,
        pjob->ji_wattr,
        JOB_ATR_LAST,
        preq->rq_perm,
        &pstat->brp_attr,
        bad,
        IsOwner))
    {
    return(PBSE_NOATTR);
    }

  return (0);
  }  /* END status_job() */
Exemple #7
0
pbs_queue *
que_alloc(char *name)
{
	int        i;
	pbs_queue *pq;


	pq = (pbs_queue *)malloc(sizeof(pbs_queue));
	if (pq == (pbs_queue *)0) {
		log_err(errno, "que_alloc", "no memory");
		return ((pbs_queue *)0);
	}
	(void)memset((char *)pq, (int)0, (size_t)sizeof(pbs_queue));
	pq->qu_qs.qu_type = QTYPE_Unset;
	CLEAR_HEAD(pq->qu_jobs);
	CLEAR_LINK(pq->qu_link);

	strncpy(pq->qu_qs.qu_name, name, PBS_MAXQUEUENAME);
	append_link(&svr_queues, &pq->qu_link, pq);
	server.sv_qs.sv_numque++;

	/* set the working attributes to "unspecified" */

	for (i=0; i<(int)QA_ATR_LAST; i++) {
		clear_attr(&pq->qu_attr[i], &que_attr_def[i]);
	}

	return (pq);
}
Exemple #8
0
/**
 * @brief
 * 		sched_alloc - allocate space for a pbs_sched structure and
 * 		initialize attributes to "unset" and pbs_sched object is added
 * 		to svr_allscheds list
 *
 * @param[in]	sched_name	- scheduler  name
 *
 * @return	pbs_sched *
 * @retval	null	- space not available.
 */
pbs_sched *
sched_alloc(char *sched_name)
{
	int i;
	pbs_sched *psched;

	psched = calloc(1, sizeof(pbs_sched));

	if (psched == NULL) {
		log_err(errno, __func__, "Unable to allocate memory (malloc error)");
		return NULL;
	}

	CLEAR_LINK(psched->sc_link);
	strncpy(psched->sc_name, sched_name, PBS_MAXSCHEDNAME);
	psched->sc_name[PBS_MAXSCHEDNAME] = '\0';
	psched->svr_do_schedule = SCH_SCHEDULE_NULL;
	psched->svr_do_sched_high = SCH_SCHEDULE_NULL;
	psched->scheduler_sock = -1;
	psched->scheduler_sock2 = -1;
	append_link(&svr_allscheds, &psched->sc_link, psched);

	/* set the working attributes to "unspecified" */

	for (i = 0; i < (int) SCHED_ATR_LAST; i++) {
		clear_attr(&psched->sch_attr[i], &sched_attr_def[i]);
	}

	return (psched);
}
void add_dest(

  job *jobp)

  {
  badplace  *bp;
  char      *baddest = jobp->ji_qs.ji_destin;

  bp = (badplace *)calloc(1, sizeof(badplace));

  if (bp == NULL)
    {
    log_err(errno, __func__, msg_err_malloc);

    return;
    }

  CLEAR_LINK(bp->bp_link);

  strcpy(bp->bp_dest, baddest);

  append_link(&jobp->ji_rejectdest, &bp->bp_link, bp);

  return;
  }  /* END add_dest() */
Exemple #10
0
int
encode_unkn(attribute *attr, pbs_list_head *phead, char *atname, char *rsname, int mode, svrattrl **rtnl)
{
	svrattrl *plist;
	svrattrl *pnew;
	svrattrl *xprior = NULL;
	int	  first = 1;

	if (!attr)
		return (-2);

	plist = (svrattrl *)GET_NEXT(attr->at_val.at_list);
	if (plist == NULL)
		return (0);

	while (plist != NULL) {
		pnew = (svrattrl *)malloc(plist->al_tsize);
		if (pnew == NULL)
			return (-1);
		CLEAR_LINK(pnew->al_link);
		pnew->al_sister = NULL;
		pnew->al_tsize  = plist->al_tsize;
		pnew->al_nameln = plist->al_nameln;
		pnew->al_rescln = plist->al_rescln;
		pnew->al_valln  = plist->al_valln;
		pnew->al_flags  = plist->al_flags;
		pnew->al_refct  = 1;

		pnew->al_name = (char *)pnew + sizeof(svrattrl);
		(void)memcpy(pnew->al_name, plist->al_name, plist->al_nameln);
		if (plist->al_rescln) {
			pnew->al_resc = pnew->al_name + pnew->al_nameln;
			(void)memcpy(pnew->al_resc, plist->al_resc,
				plist->al_rescln);
		} else {
			pnew->al_resc = NULL;
		}
		if (plist->al_valln) {
			pnew->al_value = pnew->al_name + pnew->al_nameln +
				pnew->al_rescln;
			(void)memcpy(pnew->al_value, plist->al_value,
				pnew->al_valln);
		}
		if (phead)
			append_link(phead, &pnew->al_link, pnew);
		if (first) {
			if (rtnl)
				*rtnl = pnew;
			first = 0;
		} else {
			if (xprior)
				xprior->al_sister = pnew;
		}
		xprior = pnew;

		plist = (svrattrl *)GET_NEXT(plist->al_link);
	}
	return (1);
}
Exemple #11
0
job *job_alloc(void)

  {
  job *pj;

  pj = (job *)calloc(1, sizeof(job));

  if (pj == NULL)
    {
    log_err(errno, "job_alloc", "no memory");

    return(NULL);
    }

  pj->ji_qs.qs_version = PBS_QS_VERSION;

  CLEAR_LINK(pj->ji_alljobs);
  CLEAR_LINK(pj->ji_jobque);

  CLEAR_HEAD(pj->ji_tasks);
  pj->ji_taskid = TM_NULL_TASK + 1;
  pj->ji_numnodes = 0;
  pj->ji_numvnod  = 0;
  pj->ji_hosts = NULL;
  pj->ji_vnods = NULL;
  pj->ji_resources = NULL;
  pj->ji_obit = TM_NULL_EVENT;
  pj->ji_preq = NULL;
  pj->ji_nodekill = TM_ERROR_NODE;
  pj->ji_flags = 0;
  pj->ji_globid = NULL;
  pj->ji_stdout = 0;
  pj->ji_stderr = 0;
  pj->ji_qs.ji_un.ji_momt.ji_exitstat = 0;
  pj->ji_job_is_being_rerun = 0;

  pj->ji_momhandle = -1;  /* mark mom connection invalid */

  /* set the working attributes to "unspecified" */
  job_init_wattr(pj);

  return(pj);
  }  /* END job_alloc() */
Exemple #12
0
/**
 *
 * @brief
 * 	Creates a task of type 'type', 'event_id', and when task is dispatched,
 *	execute func with argument 'parm'. The task is added to
 *	'task_list_immed' if 'type' is  WORK_Immed; otherwise, task is added
 *	'task_list_event'.
 *
 * @param[in]	type - of task
 * @param[in]	event_id - event id of the task
 * @param[in]	func - function that will be executed in behalf of the task
 * @param[in]	parm - parameter to 'func'
 *
 * @return struct work_task *
 * @retval <a work task entry>	- for success
 * @retval NULL			- for any error
 *
 */
struct work_task *set_task(enum work_type type, long event_id, void (*func)(struct work_task *) , void *parm)
{
	struct work_task *pnew;
	struct work_task *pold;

	pnew = (struct work_task *)malloc(sizeof(struct work_task));
	if (pnew == (struct work_task *)0)
		return ((struct work_task *)0);
	CLEAR_LINK(pnew->wt_linkall);
	CLEAR_LINK(pnew->wt_linkobj);
	CLEAR_LINK(pnew->wt_linkobj2);
	pnew->wt_event = event_id;
	pnew->wt_event2 = NULL;
	pnew->wt_type  = type;
	pnew->wt_func  = func;
	pnew->wt_parm1 = parm;
	pnew->wt_parm2 = NULL;
	pnew->wt_parm3 = NULL;
	pnew->wt_aux   = 0;
	pnew->wt_aux2  = 0;

	if (type == WORK_Immed)
		append_link(&task_list_immed, &pnew->wt_linkall, pnew);
	else if (type == WORK_Timed) {
		pold = (struct work_task *)GET_NEXT(task_list_timed);
		while (pold) {
			if (pold->wt_event > pnew->wt_event)
				break;
			pold = (struct work_task *)GET_NEXT(pold->wt_linkall);
		}
		if (pold)
			insert_link(&pold->wt_linkall, &pnew->wt_linkall, pnew,
				LINK_INSET_BEFORE);
		else
			append_link(&task_list_timed, &pnew->wt_linkall, pnew);
	} else
		append_link(&task_list_event, &pnew->wt_linkall, pnew);
	return (pnew);
}
Exemple #13
0
int copy_attribute_list(

  batch_request *preq,
  batch_request *preq_tmp)

  {
  svrattrl             *pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_manager.rq_attr);
  tlist_head           *phead = &preq_tmp->rq_ind.rq_manager.rq_attr;
  svrattrl             *newpal = NULL;

  while (pal != NULL)
    {
    newpal = (svrattrl *)calloc(1, pal->al_tsize + 1);
    if (!newpal)
      {
      free_br(preq_tmp);
      return(PBSE_SYSTEM);
      }

    CLEAR_LINK(newpal->al_link);

    newpal->al_atopl.next = 0;
    newpal->al_tsize = pal->al_tsize + 1;
    newpal->al_nameln = pal->al_nameln;
    newpal->al_flags  = pal->al_flags;
    newpal->al_atopl.name = (char *)newpal + sizeof(svrattrl);
    strcpy((char *)newpal->al_atopl.name, pal->al_atopl.name);
    newpal->al_nameln = pal->al_nameln;
    newpal->al_atopl.resource = newpal->al_atopl.name + newpal->al_nameln;

    if (pal->al_atopl.resource != NULL)
      strcpy((char *)newpal->al_atopl.resource, pal->al_atopl.resource);

    newpal->al_rescln = pal->al_rescln;
    newpal->al_atopl.value = newpal->al_atopl.name + newpal->al_nameln + newpal->al_rescln;
    strcpy((char *)newpal->al_atopl.value, pal->al_atopl.value);
    newpal->al_valln = pal->al_valln;
    newpal->al_atopl.op = pal->al_atopl.op;

    pal = (struct svrattrl *)GET_NEXT(pal->al_link);
    }

  if ((phead != NULL) &&
       (newpal != NULL))
    append_link(phead, &newpal->al_link, newpal);

  return(PBSE_NONE);
  } /* END copy_attribute_list() */
Exemple #14
0
void
req_stat_svr(struct batch_request *preq)
{
	svrattrl	   *pal;
	struct batch_reply *preply;
	struct brp_status  *pstat;


	/* update count and state counts from sv_numjobs and sv_jobstates */

	server.sv_attr[(int)SRV_ATR_TotalJobs].at_val.at_long = server.sv_qs.sv_numjobs;
	server.sv_attr[(int)SRV_ATR_TotalJobs].at_flags |= ATR_VFLAG_SET|ATR_VFLAG_MODCACHE;
	update_state_ct(&server.sv_attr[(int)SRV_ATR_JobsByState],
		server.sv_jobstates,
		server.sv_jobstbuf);

	update_license_ct(&server.sv_attr[(int)SRV_ATR_license_count],
		server.sv_license_ct_buf);

	/* allocate a reply structure and a status sub-structure */

	preply = &preq->rq_reply;
	preply->brp_choice = BATCH_REPLY_CHOICE_Status;
	CLEAR_HEAD(preply->brp_un.brp_status);

	pstat = (struct brp_status *)malloc(sizeof(struct brp_status));
	if (pstat == NULL) {
		reply_free(preply);
		req_reject(PBSE_SYSTEM, 0, preq);
		return;
	}
	CLEAR_LINK(pstat->brp_stlink);
	(void)strcpy(pstat->brp_objname, server_name);
	pstat->brp_objtype = MGR_OBJ_SERVER;
	CLEAR_HEAD(pstat->brp_attr);
	append_link(&preply->brp_un.brp_status, &pstat->brp_stlink, pstat);

	/* add attributes to the status reply */

	bad = 0;
	pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);
	if (status_attrib(pal, svr_attr_def, server.sv_attr, SRV_ATR_LAST,
		preq->rq_perm, &pstat->brp_attr, &bad))
		reply_badattr(PBSE_NOATTR, bad, pal, preq);
	else
		(void)reply_send(preq);
}
Exemple #15
0
static int
status_que(pbs_queue *pque, struct batch_request *preq, pbs_list_head *pstathd)
{
	struct brp_status *pstat;
	svrattrl	  *pal;

	if ((preq->rq_perm & ATR_DFLAG_RDACC) == 0)
		return (PBSE_PERM);

	/* ok going to do status, update count and state counts from qu_qs */

	if (!svr_chk_history_conf()) {
		pque->qu_attr[(int)QA_ATR_TotalJobs].at_val.at_long = pque->qu_numjobs;
	} else {
		pque->qu_attr[(int)QA_ATR_TotalJobs].at_val.at_long = pque->qu_numjobs -
			(pque->qu_njstate[JOB_STATE_MOVED] + pque->qu_njstate[JOB_STATE_FINISHED]);
	}
	pque->qu_attr[(int)QA_ATR_TotalJobs].at_flags |= ATR_VFLAG_SET|ATR_VFLAG_MODCACHE;

	update_state_ct(&pque->qu_attr[(int)QA_ATR_JobsByState],
		pque->qu_njstate,
		pque->qu_jobstbuf);

	/* allocate status sub-structure and fill in header portion */

	pstat = (struct brp_status *)malloc(sizeof(struct brp_status));
	if (pstat == NULL)
		return (PBSE_SYSTEM);
	pstat->brp_objtype = MGR_OBJ_QUEUE;
	(void)strcpy(pstat->brp_objname, pque->qu_qs.qu_name);
	CLEAR_LINK(pstat->brp_stlink);
	CLEAR_HEAD(pstat->brp_attr);
	append_link(pstathd, &pstat->brp_stlink, pstat);

	/* add attributes to the status reply */

	bad = 0;
	pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);
	if (status_attrib(pal, que_attr_def, pque->qu_attr, QA_ATR_LAST,
		preq->rq_perm, &pstat->brp_attr, &bad))
		return (PBSE_NOATTR);

	return (0);
}
struct batch_request *alloc_br(int type)
{
	struct batch_request *req;

	req= (struct batch_request *)malloc(sizeof(struct batch_request));
	if (req== NULL)
		log_err(errno, "alloc_br", msg_err_malloc);
	else {
		memset((void *)req, (int)0, sizeof(struct batch_request));
		req->rq_type = type;
		CLEAR_LINK(req->rq_link);
		req->rq_conn = -1;		/* indicate not connected */
		req->rq_orgconn = -1;		/* indicate not connected */
		req->rq_time = time_now;
		req->rpp_ack = 1; /* enable acks to be passed by rpp by default */
		req->isrpp = 0; /* not rpp by default */
		req->rppcmd_msgid = NULL; /* NULL msgid to boot */
		req->rq_reply.brp_choice = BATCH_REPLY_CHOICE_NULL;
		append_link(&svr_requests, &req->rq_link, req);
	}
	return (req);
}
Exemple #17
0
static struct resource_cost *add_cost_entry(

  pbs_attribute *patr,
  resource_def  *prdef)

  {
  struct resource_cost *pcost;

  pcost = (struct resource_cost *)calloc(1, sizeof(struct resource_cost));

  if (pcost != NULL)
    {
    CLEAR_LINK(pcost->rc_link);

    pcost->rc_def = prdef;
    pcost->rc_cost = 0;

    append_link(&patr->at_val.at_list, &pcost->rc_link, pcost);
    }

  return(pcost);
  }
Exemple #18
0
svrattrl *attrlist_create(const char *aname, const char *rname, int vsize)
  {
  svrattrl *pal;
  size_t    asz;
  size_t    rsz;

  asz = strlen(aname) + 1;     /* pbs_attribute name,allow for null term */

  if (rname == NULL)      /* resource name only if type resource */
    rsz = 0;
  else
    rsz = strlen(rname) + 1;

  pal = (svrattrl *)calloc(1, sizeof(svrattrl) + asz + rsz + vsize);

  CLEAR_LINK(pal->al_link); /* clear link */

  pal->al_atopl.next = 0;
  pal->al_tsize = sizeof(svrattrl) + asz + rsz + vsize;  /* set various string sizes */
  pal->al_nameln = asz;
  pal->al_rescln = rsz;
  pal->al_valln  = vsize;
  pal->al_flags  = 0;
  pal->al_op     = SET;

  /* point ptrs to name, resc, and val strings to memory after svrattrl struct */

  pal->al_name = (char *)pal + sizeof(svrattrl);

  pal->al_resc = NULL;

  pal->al_value = pal->al_name + asz + rsz;

  strcpy(pal->al_name, aname); /* copy name right after struct */

  return(pal);
  }
Exemple #19
0
static int
status_resv(resc_resv *presv, struct batch_request *preq, pbs_list_head *pstathd)
{
	struct brp_status *pstat;
	svrattrl	  *pal;

	if ((preq->rq_perm & ATR_DFLAG_RDACC) == 0)
		return (PBSE_PERM);

	/*first do any need update to attributes from
	 *"quick save" area of the resc_resv structure
	 */

	/*now allocate status sub-structure and fill header portion*/

	pstat = (struct brp_status *)malloc(sizeof(struct brp_status));
	if (pstat == NULL)
		return (PBSE_SYSTEM);

	pstat->brp_objtype = MGR_OBJ_RESV;
	(void)strcpy(pstat->brp_objname, presv->ri_qs.ri_resvID);
	CLEAR_LINK(pstat->brp_stlink);
	CLEAR_HEAD(pstat->brp_attr);
	append_link(pstathd, &pstat->brp_stlink, pstat);

	/*finally, add the requested attributes to the status reply*/

	bad = 0;	/*global: record ordinal position where got error*/
	pal = (svrattrl *) GET_NEXT(preq->rq_ind.rq_status.rq_attr);

	if (status_attrib(pal, resv_attr_def, presv->ri_wattr,
		RESV_ATR_LAST, preq->rq_perm, &pstat->brp_attr, &bad) == 0)
		return (0);
	else
		return (PBSE_NOATTR);
}
Exemple #20
0
int status_job(

  job           *pjob, /* ptr to job to status */
  batch_request *preq,
  svrattrl      *pal, /* specific attributes to status */
  tlist_head    *pstathd, /* RETURN: head of list to append status to */
  bool           condensed,
  int           *bad) /* RETURN: index of first bad pbs_attribute */

  {
  struct brp_status *pstat;
  int                IsOwner = 0;
  long               query_others = 0;
  long               condensed_timeout = JOB_CONDENSED_TIMEOUT;

  /* Make sure procct is removed from the job 
     resource attributes */
  remove_procct(pjob);

  /* see if the client is authorized to status this job */
  if (svr_authorize_jobreq(preq, pjob) == 0)
    IsOwner = 1;

  get_svr_attr_l(SRV_ATR_query_others, &query_others);
  if (!query_others)
    {
    if (IsOwner == 0)
      {
      return(PBSE_PERM);
      }
    }
  
  get_svr_attr_l(SRV_ATR_job_full_report_time, &condensed_timeout);

  // if the job has been modified within the timeout, send the full output
  if ((condensed == true) &&
      (time(NULL) < pjob->ji_mod_time + condensed_timeout))
    condensed = false;

  /* allocate reply structure and fill in header portion */
  if ((pstat = (struct brp_status *)calloc(1, sizeof(struct brp_status))) == NULL)
    {
    return(PBSE_SYSTEM);
    }

  CLEAR_LINK(pstat->brp_stlink);

  pstat->brp_objtype = MGR_OBJ_JOB;

  strcpy(pstat->brp_objname, pjob->ji_qs.ji_jobid);

  CLEAR_HEAD(pstat->brp_attr);

  append_link(pstathd, &pstat->brp_stlink, pstat);

  /* add attributes to the status reply */

  *bad = 0;

  if (status_attrib(
        pal,
        job_attr_def,
        pjob->ji_wattr,
        JOB_ATR_LAST,
        preq->rq_perm,
        &pstat->brp_attr,
        condensed,
        bad,
        IsOwner))
    {
    return(PBSE_NOATTR);
    }

  return (0);
  }  /* END status_job() */
Exemple #21
0
int copy_batchrequest(
    
  struct batch_request **newreq,
  struct batch_request  *preq,
  int                    type,
  int                    jobid)

  {
  struct batch_request *request;
  svrattrl             *pal = NULL;
  svrattrl             *newpal = NULL;
  tlist_head           *phead = NULL;
  char                 *ptr1;
  char                 *ptr2;
  char                  newjobname[PBS_MAXSVRJOBID+1];
  
  request = alloc_br(type);
  if (request)
    {
    request->rq_type = preq->rq_type;
    request->rq_perm = preq->rq_perm;
    request->rq_fromsvr = preq->rq_fromsvr;
    request->rq_conn = preq->rq_conn;
    request->rq_orgconn = preq->rq_orgconn;
    request->rq_extsz = preq->rq_extsz;
    request->rq_time = preq->rq_time;
    strcpy(request->rq_user, preq->rq_user);
    strcpy(request->rq_host, preq->rq_host);
    request->rq_reply.brp_choice = preq->rq_reply.brp_choice;
    request->rq_noreply = preq->rq_noreply;
    /* we need to copy rq_extend if there is any data */
    if (preq->rq_extend)
      {
      request->rq_extend = (char *)calloc(1, strlen(preq->rq_extend) + 1);
      if (request->rq_extend == NULL)
        {
        free_br(request);
        return(PBSE_SYSTEM);
        }
      strcpy(request->rq_extend, preq->rq_extend);
      }
    /* remember the batch_request we copied */
    request->rq_extra = (void *)preq;
    
    switch(preq->rq_type)
      {
      /* This function was created for a modify arracy request (PBS_BATCH_ModifyJob)
         the preq->rq_ind structure was allocated in dis_request_read. If other
         BATCH types are needed refer to that function to see how the rq_ind structure
         was allocated and then copy it here. */
      case PBS_BATCH_DeleteJob:
        
      case PBS_BATCH_HoldJob:
        
      case PBS_BATCH_CheckpointJob:
        
      case PBS_BATCH_ModifyJob:
        
      case PBS_BATCH_AsyModifyJob:
        /* based on how decode_DIS_Manage allocates data */
        CLEAR_HEAD(request->rq_ind.rq_manager.rq_attr);
        
        phead = &request->rq_ind.rq_manager.rq_attr;
        request->rq_ind.rq_manager.rq_cmd = preq->rq_ind.rq_manager.rq_cmd;
        request->rq_ind.rq_manager.rq_objtype = preq->rq_ind.rq_manager.rq_objtype;
        /* If this is a job array it is possible we only have the array name
           and not the individual job. We need to find out what we have and
           modify the name if needed */
        ptr1 = strstr(preq->rq_ind.rq_manager.rq_objname, "[]");
        if ((ptr1) && (jobid != -1))
          {
          ptr1++;
          strcpy(newjobname, preq->rq_ind.rq_manager.rq_objname);
          ptr2 = strstr(newjobname, "[]");
          ptr2++;
          *ptr2 = 0;
          sprintf(request->rq_ind.rq_manager.rq_objname,"%s%d%s", 
            newjobname,
            jobid,
            ptr1);
          }
        else
          strcpy(request->rq_ind.rq_manager.rq_objname, preq->rq_ind.rq_manager.rq_objname);
        
        /* copy the attribute list */
        pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_manager.rq_attr);
        while(pal != NULL)
          {
          newpal = (svrattrl *)calloc(1, pal->al_tsize + 1);
          if (!newpal)
            {
            free_br(request);
            return(PBSE_SYSTEM);
            }
          CLEAR_LINK(newpal->al_link);
          
          newpal->al_atopl.next = 0;
          newpal->al_tsize = pal->al_tsize + 1;
          newpal->al_nameln = pal->al_nameln;
          newpal->al_flags  = pal->al_flags;
          newpal->al_atopl.name = (char *)newpal + sizeof(svrattrl);
          strcpy(newpal->al_atopl.name, pal->al_atopl.name);
          newpal->al_nameln = pal->al_nameln;
          newpal->al_atopl.resource = newpal->al_atopl.name + newpal->al_nameln;
          if (pal->al_atopl.resource != NULL)
            strcpy(newpal->al_atopl.resource, pal->al_atopl.resource);
          newpal->al_rescln = pal->al_rescln;
          newpal->al_atopl.value = newpal->al_atopl.name + newpal->al_nameln + newpal->al_rescln;
          strcpy(newpal->al_atopl.value, pal->al_atopl.value);
          newpal->al_valln = pal->al_valln;
          newpal->al_atopl.op = pal->al_atopl.op;
          
          pal = (struct svrattrl *)GET_NEXT(pal->al_link);
          
          }
        
        break;

      case PBS_BATCH_SignalJob:

        strcpy(request->rq_ind.rq_signal.rq_jid, preq->rq_ind.rq_signal.rq_jid);
        strcpy(request->rq_ind.rq_signal.rq_signame, preq->rq_ind.rq_signal.rq_signame);
        request->rq_extra = strdup(preq->rq_extra);

        break;

      case PBS_BATCH_MessJob:

        strcpy(request->rq_ind.rq_message.rq_jid, preq->rq_ind.rq_message.rq_jid);
        request->rq_ind.rq_message.rq_file = preq->rq_ind.rq_message.rq_file;
        strcpy(request->rq_ind.rq_message.rq_text, preq->rq_ind.rq_message.rq_text);

        break;
        
      default:

        break;
        
      }

    if ((phead != NULL) &&
        (newpal != NULL))
      append_link(phead, &newpal->al_link, newpal);
    
    *newreq = request;
    return(0);
    
    }
  else
    return(PBSE_SYSTEM);
  }
static void req_stat_job_step2(

  struct stat_cntl *cntl)  /* I/O (free'd on return) */

  {
  svrattrl              *pal;
  job                   *pjob = NULL;

  struct batch_request  *preq;
  struct batch_reply    *preply;
  int                    rc = 0;
  enum TJobStatTypeEnum  type;
  pbs_queue             *pque = NULL;
  int                    exec_only = 0;

  int                    bad = 0;
  long                   DTime;  /* delta time - only report full pbs_attribute list if J->MTime > DTime */
  static svrattrl       *dpal = NULL;
  int                    job_array_index = 0;
  job_array             *pa = NULL;
  char                   log_buf[LOCAL_LOG_BUF_SIZE];
  int                    iter;
  time_t                 time_now = time(NULL);
  long                   poll_jobs = 0;
  char                   job_id[PBS_MAXSVRJOBID+1];
  int                    job_substate = -1;
  time_t                 job_momstattime = -1;

  preq   = cntl->sc_origrq;
  type   = (enum TJobStatTypeEnum)cntl->sc_type;
  preply = &preq->rq_reply;

  /* See pbs_server_attributes(1B) for details on "poll_jobs" behaviour */

  if (dpal == NULL)
    {
    /* build 'delta' pbs_attribute list */

    svrattrl *tpal;

    tlist_head dalist;

    int aindex;

    int atrlist[] =
      {
      JOB_ATR_jobname,
      JOB_ATR_resc_used,
      JOB_ATR_LAST
      };

    CLEAR_LINK(dalist);

    for (aindex = 0;atrlist[aindex] != JOB_ATR_LAST;aindex++)
      {
      if ((tpal = attrlist_create("", "", 23)) == NULL)
        {
        return;
        }

      tpal->al_valln = atrlist[aindex];

      if (dpal == NULL)
        dpal = tpal;

      append_link(&dalist, &tpal->al_link, tpal);
      }
    }  /* END if (dpal == NULL) */

  if (type == tjstArray)
    {
    pa = get_array(preq->rq_ind.rq_status.rq_id);

    if (pa == NULL)
      {
      req_reject(PBSE_UNKARRAYID, 0, preq, NULL, "unable to find array");
      return;
      }
    }

  iter = -1;

  get_svr_attr_l(SRV_ATR_PollJobs, &poll_jobs);
  if (!poll_jobs)
    {
    /* polljobs not set - indicates we may need to obtain fresh data from
       MOM */

    if (cntl->sc_jobid[0] == '\0')
      pjob = NULL;
    else
      pjob = svr_find_job(cntl->sc_jobid, FALSE);

    while (1)
      {
      if (pjob == NULL)
        {
        /* start from the first job */

        if (type == tjstJob)
          {
          pjob = svr_find_job(preq->rq_ind.rq_status.rq_id, FALSE);
          }
        else if (type == tjstQueue)
          {
          pjob = next_job(cntl->sc_pque->qu_jobs,&iter);
          }
        else if (type == tjstArray)
          {
          job_array_index = 0;
          /* increment job_array_index until we find a non-null pointer or hit the end */
          while (job_array_index < pa->ai_qs.array_size)
            {
            if (pa->job_ids[job_array_index] != NULL)
              {
              if ((pjob = svr_find_job(pa->job_ids[job_array_index], FALSE)) != NULL)
                {
                unlock_ji_mutex(pjob, __func__, "2", LOGLEVEL);
                break;
                }
              }

            job_array_index++;
            }
          }
        else
          {
          pjob = next_job(&alljobs,&iter);
          }

        }    /* END if (pjob == NULL) */
      else
        {
        strcpy(job_id, pjob->ji_qs.ji_jobid);
        unlock_ji_mutex(pjob, __func__, "3", LOGLEVEL);

        if (type == tjstJob)
          break;

        if (type == tjstQueue)
          pjob = next_job(cntl->sc_pque->qu_jobs,&iter);
        else if (type == tjstArray)
          {
          pjob = NULL;
          /* increment job_array_index until we find a non-null pointer or hit the end */
          while (++job_array_index < pa->ai_qs.array_size)
            {
            if (pa->job_ids[job_array_index] != NULL)
              {
              if ((pjob = svr_find_job(pa->job_ids[job_array_index], FALSE)) != NULL)
                {
                unlock_ji_mutex(pjob, __func__, "3", LOGLEVEL);
                break;
                }
              }
            }
          }
        else
          pjob = next_job(&alljobs,&iter);
          
        }

      if (pjob == NULL)
        break;

      strcpy(job_id, pjob->ji_qs.ji_jobid);
      job_substate = pjob->ji_qs.ji_substate;
      job_momstattime = pjob->ji_momstat;
      strcpy(cntl->sc_jobid, job_id);
      unlock_ji_mutex(pjob, __func__, "4", LOGLEVEL);
      pjob = NULL;

      /* PBS_RESTAT_JOB defaults to 30 seconds */
      if ((job_substate == JOB_SUBSTATE_RUNNING) &&
          ((time_now - job_momstattime) > JobStatRate))
        {
        /* go to MOM for status */
        if ((rc = stat_to_mom(job_id, cntl)) == PBSE_MEM_MALLOC)
          break;

        if (rc != 0)
          {
          pjob = svr_find_job(job_id, FALSE);

          rc = 0;

          continue;
          }
        
        if (pa != NULL)
          unlock_ai_mutex(pa, __func__, "1", LOGLEVEL);

        return; /* will pick up after mom replies */
        }
      }    /* END while(1) */

    if (rc != 0)
      {
      if (pa != NULL)
        unlock_ai_mutex(pa, __func__, "2", LOGLEVEL);

      reply_free(preply);

      req_reject(rc, 0, preq, NULL, "cannot get update from mom");

      return;
      }
    }    /* END if (!server.sv_attr[SRV_ATR_PollJobs].at_val.at_long) */

  /*
   * now ready for part 3, building the status reply,
   * loop through again
   */

  if ((type == tjstSummarizeArraysQueue) || 
      (type == tjstSummarizeArraysServer))
    {
    /* No array can be owned for these options */
    update_array_statuses();
    }

  if (type == tjstJob)
    pjob = svr_find_job(preq->rq_ind.rq_status.rq_id, FALSE);

  else if (type == tjstQueue)
    pjob = next_job(cntl->sc_pque->qu_jobs,&iter);

  else if (type == tjstSummarizeArraysQueue)
    pjob = next_job(cntl->sc_pque->qu_jobs_array_sum,&iter);

  else if (type == tjstSummarizeArraysServer)
    pjob = next_job(&array_summary,&iter);

  else if (type == tjstArray)
    {
    job_array_index = -1;
    pjob = NULL;
    /* increment job_array_index until we find a non-null pointer or hit the end */
    while (++job_array_index < pa->ai_qs.array_size)
      {
      if (pa->job_ids[job_array_index] != NULL)
        {
        if ((pjob = svr_find_job(pa->job_ids[job_array_index], FALSE)) != NULL)
          {
          break;
          }
        }
      }
    }
  else
    pjob = next_job(&alljobs,&iter);

  DTime = 0;

  if (preq->rq_extend != NULL)
    {
    char *ptr;

    /* FORMAT:  { EXECQONLY | DELTA:<EPOCHTIME> } */

    if (strstr(preq->rq_extend, EXECQUEONLY))
      exec_only = 1;

    ptr = strstr(preq->rq_extend, "DELTA:");

    if (ptr != NULL)
      {
      ptr += strlen("delta:");

      DTime = strtol(ptr, NULL, 10);
      }
    }


  if ((type == tjstTruncatedServer) || 
      (type == tjstTruncatedQueue))
    {
    long sentJobCounter;
    long qjcounter;
    long qmaxreport;
    int  iter = -1;

    /* loop through all queues */
    while ((pque = next_queue(&svr_queues,&iter)) != NULL)
      {
      qjcounter = 0;

      if ((exec_only == 1) &&
          (pque->qu_qs.qu_type != QTYPE_Execution))
        {
        /* ignore routing queues */
        unlock_queue(pque, __func__, "ignore queue", LOGLEVEL);
        continue;
        }

      if (((pque->qu_attr[QA_ATR_MaxReport].at_flags & ATR_VFLAG_SET) != 0) &&
          (pque->qu_attr[QA_ATR_MaxReport].at_val.at_long >= 0))
        {
        qmaxreport = pque->qu_attr[QA_ATR_MaxReport].at_val.at_long;
        }
      else
        {
        qmaxreport = TMAX_JOB;
        }

      if (LOGLEVEL >= 5)
        {
        sprintf(log_buf,"giving scheduler up to %ld idle jobs in queue %s\n",
          qmaxreport,
          pque->qu_qs.qu_name);

        log_event(PBSEVENT_SYSTEM,PBS_EVENTCLASS_QUEUE,pque->qu_qs.qu_name,log_buf);
        }

      sentJobCounter = 0;

      /* loop through jobs in queue */
      if (pjob != NULL)
        unlock_ji_mutex(pjob, __func__, "5", LOGLEVEL);

      iter = -1;

      while ((pjob = next_job(pque->qu_jobs,&iter)) != NULL)
        {
        if ((qjcounter >= qmaxreport) &&
            (pjob->ji_qs.ji_state == JOB_STATE_QUEUED))
          {
          /* max_report of queued jobs reached for queue */
          unlock_ji_mutex(pjob, __func__, "6", LOGLEVEL);

          continue;
          }

        pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);

        rc = status_job(
               pjob,
               preq,
               (pjob->ji_wattr[JOB_ATR_mtime].at_val.at_long >= DTime) ? pal : dpal,
               &preply->brp_un.brp_status,
               &bad);

        if ((rc != 0) && (rc != PBSE_PERM))
          {
          req_reject(rc, bad, preq, NULL, NULL);

          if (pa != NULL)
            {
            unlock_ai_mutex(pa, __func__, "1", LOGLEVEL);
            }
          unlock_ji_mutex(pjob, __func__, "7", LOGLEVEL);
          unlock_queue(pque, __func__, "perm", LOGLEVEL);
          return;
          }

        sentJobCounter++;

        if (pjob->ji_qs.ji_state == JOB_STATE_QUEUED)
          qjcounter++;

        unlock_ji_mutex(pjob, __func__, "8", LOGLEVEL);
        }    /* END foreach (pjob from pque) */

      if (LOGLEVEL >= 5)
        {
        sprintf(log_buf,"sent scheduler %ld total jobs for queue %s\n",
          sentJobCounter,
          pque->qu_qs.qu_name);

        log_event(PBSEVENT_SYSTEM,PBS_EVENTCLASS_QUEUE,pque->qu_qs.qu_name,log_buf);
        }
    
      unlock_queue(pque, __func__, "end while", LOGLEVEL);
      }      /* END for (pque) */
      
    if (pa != NULL)
      unlock_ai_mutex(pa, __func__, "1", LOGLEVEL);

    reply_send_svr(preq);

    return;
    }        /* END if ((type == tjstTruncatedServer) || ...) */

  while (pjob != NULL)
    {
    /* go ahead and build the status reply for this job */

    if (exec_only)
      {
      if (cntl->sc_pque != NULL)
        {
        if (cntl->sc_pque->qu_qs.qu_type != QTYPE_Execution)
          goto nextjob;
        }
      else
        {
        if (pa != NULL)
          pthread_mutex_unlock(pa->ai_mutex);
        pque = get_jobs_queue(&pjob);
        if (pa != NULL)
          pthread_mutex_lock(pa->ai_mutex);

        if ((pjob == NULL) ||
            (pque == NULL))
          goto nextjob;
        
        if (pque->qu_qs.qu_type != QTYPE_Execution)
          {
          unlock_queue(pque, __func__, "not exec", LOGLEVEL);
        
          goto nextjob;
          }

        unlock_queue(pque, __func__, "exec", LOGLEVEL);
        }
      }

    pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);

    rc = status_job(
           pjob,
           preq,
           pal,
           &preply->brp_un.brp_status,
           &bad);

    if ((rc != 0) && 
        (rc != PBSE_PERM))
      {
      if (pa != NULL)
        {
        unlock_ai_mutex(pa, __func__, "1", LOGLEVEL);
        }
      unlock_ji_mutex(pjob, __func__, "9", LOGLEVEL);

      req_reject(rc, bad, preq, NULL, NULL);

      return;
      }

    /* get next job */

nextjob:

    if (pjob != NULL)
      unlock_ji_mutex(pjob, __func__, "10", LOGLEVEL);

    if (type == tjstJob)
      break;

    if (type == tjstQueue)
      pjob = next_job(cntl->sc_pque->qu_jobs,&iter);
    else if (type == tjstSummarizeArraysQueue)
      pjob = next_job(cntl->sc_pque->qu_jobs_array_sum,&iter);
    else if (type == tjstSummarizeArraysServer)
      pjob = next_job(&array_summary,&iter);
    else if (type == tjstArray)
      {
      pjob = NULL;
      /* increment job_array_index until we find a non-null pointer or hit the end */
      while (++job_array_index < pa->ai_qs.array_size)
        {
        if (pa->job_ids[job_array_index] != NULL)
          {
          if ((pjob = svr_find_job(pa->job_ids[job_array_index], FALSE)) != NULL)
            {
            break;
            }
          }
        }
      }
    else
      pjob = next_job(&alljobs,&iter);

    rc = 0;
    }  /* END while (pjob != NULL) */

  if (pa != NULL)
    {
    unlock_ai_mutex(pa, __func__, "1", LOGLEVEL);
    }
 
  reply_send_svr(preq);

  if (LOGLEVEL >= 7)
    {
    log_event(PBSEVENT_SYSTEM,
      PBS_EVENTCLASS_JOB,
      "req_statjob",
      "Successfully returned the status of queued jobs\n");
    }

  return;
  }  /* END req_stat_job_step2() */
Exemple #23
0
int req_stat_svr(

  struct batch_request *preq) /* ptr to the decoded request */

  {
  svrattrl             *pal;

  struct batch_reply   *preply;

  struct brp_status    *pstat;
  int                   bad = 0;
  char                  nc_buf[128];
  int                   numjobs;
  int                   netrates[3];

  memset(netrates, 0, sizeof(netrates));

  /* update count and state counts from sv_numjobs and sv_jobstates */
  lock_sv_qs_mutex(server.sv_qs_mutex, __func__);
  numjobs = server.sv_qs.sv_numjobs;
  unlock_sv_qs_mutex(server.sv_qs_mutex, __func__);
  
  pthread_mutex_lock(server.sv_attr_mutex);
  server.sv_attr[SRV_ATR_TotalJobs].at_val.at_long = numjobs;
  server.sv_attr[SRV_ATR_TotalJobs].at_flags |= ATR_VFLAG_SET;

  pthread_mutex_lock(server.sv_jobstates_mutex);

  update_state_ct(
    &server.sv_attr[SRV_ATR_JobsByState],
    server.sv_jobstates,
    server.sv_jobstbuf);
  
  pthread_mutex_unlock(server.sv_jobstates_mutex);

  netcounter_get(netrates);
  snprintf(nc_buf, 127, "%d %d %d", netrates[0], netrates[1], netrates[2]);

  if (server.sv_attr[SRV_ATR_NetCounter].at_val.at_str != NULL)
    free(server.sv_attr[SRV_ATR_NetCounter].at_val.at_str);
  server.sv_attr[SRV_ATR_NetCounter].at_val.at_str = strdup(nc_buf);
  if (server.sv_attr[SRV_ATR_NetCounter].at_val.at_str != NULL)
    server.sv_attr[SRV_ATR_NetCounter].at_flags |= ATR_VFLAG_SET;
  pthread_mutex_unlock(server.sv_attr_mutex);

  /* allocate a reply structure and a status sub-structure */

  preply = &preq->rq_reply;
  preply->brp_choice = BATCH_REPLY_CHOICE_Status;

  CLEAR_HEAD(preply->brp_un.brp_status);

  pstat = (struct brp_status *)calloc(1, sizeof(struct brp_status));

  if (pstat == NULL)
    {
    reply_free(preply);

    req_reject(PBSE_SYSTEM, 0, preq, NULL, NULL);
    pthread_mutex_unlock(server.sv_attr_mutex);

    return(PBSE_SYSTEM);
    }

  CLEAR_LINK(pstat->brp_stlink);

  strcpy(pstat->brp_objname, server_name);

  pstat->brp_objtype = MGR_OBJ_SERVER;

  CLEAR_HEAD(pstat->brp_attr);

  append_link(&preply->brp_un.brp_status, &pstat->brp_stlink, pstat);

  /* add attributes to the status reply */

  pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);

  if (status_attrib(
        pal,
        svr_attr_def,
        server.sv_attr,
        SRV_ATR_LAST,
        preq->rq_perm,
        &pstat->brp_attr,
        &bad,
        1))    /* IsOwner == TRUE */
    {
    reply_badattr(PBSE_NOATTR, bad, pal, preq);
    }
  else
    {
    reply_send_svr(preq);
    }
    

  return(PBSE_NONE);
  }  /* END req_stat_svr() */
Exemple #24
0
static int status_que(

  pbs_queue            *pque,     /* ptr to que to status */
  struct batch_request *preq,
  tlist_head           *pstathd)  /* head of list to append status to */

  {
  struct brp_status *pstat;
  svrattrl          *pal;
  int                rc = PBSE_NONE;
  int                bad = 0;

  if ((preq->rq_perm & ATR_DFLAG_RDACC) == 0)
    {
    return(PBSE_PERM);
    }

  /* ok going to do status, update count and state counts from qu_qs */

  pque->qu_attr[QA_ATR_TotalJobs].at_val.at_long = pque->qu_numjobs;

  pque->qu_attr[QA_ATR_TotalJobs].at_flags |= ATR_VFLAG_SET;

  update_state_ct(
    &pque->qu_attr[QA_ATR_JobsByState],
    pque->qu_njstate,
    pque->qu_jobstbuf);

  /* allocate status sub-structure and fill in header portion */

  pstat = (struct brp_status *)calloc(1, sizeof(struct brp_status));

  if (pstat == NULL)
    {
    return(PBSE_SYSTEM);
    }

  memset(pstat, 0, sizeof(struct brp_status));
  pstat->brp_objtype = MGR_OBJ_QUEUE;

  strcpy(pstat->brp_objname, pque->qu_qs.qu_name);

  CLEAR_LINK(pstat->brp_stlink);
  CLEAR_HEAD(pstat->brp_attr);

  append_link(pstathd, &pstat->brp_stlink, pstat);

  /* add attributes to the status reply */

  pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);

  if ((rc = status_attrib(
        pal,
        que_attr_def,
        pque->qu_attr,
        QA_ATR_LAST,
        preq->rq_perm,
        &pstat->brp_attr,
        &bad,
        1)) != PBSE_NONE)   /* IsOwner == TRUE */
    {
    return(rc);
    }

  return(PBSE_NONE);
  }  /* END status_que() */
Exemple #25
0
int
decode_DIS_svrattrl(int sock, pbs_list_head *phead)
{
	int		i;
	unsigned int	hasresc;
	size_t		ls;
	unsigned int	data_len;
	unsigned int	numattr;
	svrattrl       *psvrat;
	int		rc;
	size_t		tsize;


	numattr = disrui(sock, &rc);	/* number of attributes in set */
	if (rc) return rc;

	for (i=0; i<numattr; ++i) {

		data_len = disrui(sock, &rc);	/* here it is used */
		if (rc) return rc;

		tsize = sizeof(svrattrl) + data_len;
		if ((psvrat = (svrattrl *)malloc(tsize)) == 0)
			return DIS_NOMALLOC;

		CLEAR_LINK(psvrat->al_link);
		psvrat->al_sister = (svrattrl *)0;
		psvrat->al_atopl.next = 0;
		psvrat->al_tsize = tsize;
		psvrat->al_name  = (char *)psvrat + sizeof(svrattrl);
		psvrat->al_resc  = 0;
		psvrat->al_value = 0;
		psvrat->al_nameln = 0;
		psvrat->al_rescln = 0;
		psvrat->al_valln  = 0;
		psvrat->al_flags  = 0;
		psvrat->al_refct  = 1;

		if ((rc = disrfcs(sock, &ls, data_len, psvrat->al_name)) != 0)
			break;
		*(psvrat->al_name + ls++) = '\0';
		psvrat->al_nameln = (int)ls;
		data_len -= ls;

		hasresc = disrui(sock, &rc);
		if (rc) break;
		if (hasresc) {
			psvrat->al_resc = psvrat->al_name + ls;
			rc = disrfcs(sock, &ls, data_len, psvrat->al_resc);
			if (rc)
				break;
			*(psvrat->al_resc + ls++) = '\0';
			psvrat->al_rescln = (int)ls;
			data_len -= ls;
		}

		psvrat->al_value  = psvrat->al_name + psvrat->al_nameln +
			psvrat->al_rescln;
		if ((rc = disrfcs(sock, &ls, data_len, psvrat->al_value)) != 0)
			break;
		*(psvrat->al_value + ls++) = '\0';
		psvrat->al_valln = (int)ls;

		psvrat->al_op = (enum batch_op)disrui(sock, &rc);
		if (rc) break;

		append_link(phead, &psvrat->al_link, psvrat);
	}

	if (rc) {
		(void)free(psvrat);
	}

	return (rc);
}
Exemple #26
0
/* array_recov reads in  an array struct saved to disk and inserts it into
   the servers list of arrays */
int array_recov(

  char *path, 
  job_array **new_pa)

  {
  extern tlist_head svr_jobarrays;
  job_array *pa;
  array_request_node *rn;
  int fd;
  int old_version;
  int num_tokens;
  int i;
  int len;
  int rc;

  old_version = ARRAY_QS_STRUCT_VERSION;

  /* allocate the storage for the struct */
  pa = (job_array*)calloc(1,sizeof(job_array));

  if (pa == NULL)
  {
    return PBSE_SYSTEM;
  }

  /* initialize the linked list nodes */
  CLEAR_LINK(pa->all_arrays);

  CLEAR_HEAD(pa->request_tokens);

  fd = open(path, O_RDONLY, 0);

  if ( array_259_upgrade )
    {
    rc = read_and_convert_259_array(fd, pa, path);
    if(rc != PBSE_NONE)
      {
      free(pa);
      close(fd);
      return rc;
      }
    }
  else
    {

    /* read the file into the struct previously allocated.
     */

    len = read(fd, &(pa->ai_qs), sizeof(pa->ai_qs));
    if ((len < 0) || ((len < (int)sizeof(pa->ai_qs)) && (pa->ai_qs.struct_version == ARRAY_QS_STRUCT_VERSION)))
      {
      sprintf(log_buffer, "error reading %s", path);
      log_err(errno, "array_recov", log_buffer);
      free(pa);
      close(fd);
      return PBSE_SYSTEM;
      }

    if (pa->ai_qs.struct_version != ARRAY_QS_STRUCT_VERSION)
      {
      rc = array_upgrade(pa, fd, pa->ai_qs.struct_version, &old_version);
      if(rc)
        {
        sprintf(log_buffer, "Cannot upgrade array version %d to %d", pa->ai_qs.struct_version, ARRAY_QS_STRUCT_VERSION);
        log_err(errno, "array_recov", log_buffer);
        free(pa);
        close(fd);
        return rc;
        }
      }
    }

  pa->jobs = malloc(sizeof(job *) * pa->ai_qs.array_size);
  memset(pa->jobs,0,sizeof(job *) * pa->ai_qs.array_size);

  /* check to see if there is any additional info saved in the array file */
  /* check if there are any array request tokens that haven't been fully
     processed */

  if (old_version > 1)
  {
    if (read(fd, &num_tokens, sizeof(int)) != sizeof(int))
    {
      sprintf(log_buffer, "error reading token count from %s", path);
      log_err(errno, "array_recov", log_buffer);

      free(pa);
      close(fd);
      return PBSE_SYSTEM;
    }

    for (i = 0; i < num_tokens; i++)
    {
      rn = (array_request_node*)malloc(sizeof(array_request_node));

      if (read(fd, rn, sizeof(array_request_node)) != sizeof(array_request_node))
      {

        sprintf(log_buffer, "error reading array_request_node from %s", path);
        log_err(errno, "array_recov", log_buffer);

        free(rn);

        for (rn = (array_request_node*)GET_NEXT(pa->request_tokens);
            rn != NULL;
            rn = (array_request_node*)GET_NEXT(pa->request_tokens))
        {
          delete_link(&rn->request_tokens_link);
          free(rn);
        }

        free(pa);

        close(fd);
        return PBSE_SYSTEM;
      }

      CLEAR_LINK(rn->request_tokens_link);

      append_link(&pa->request_tokens, &rn->request_tokens_link, (void*)rn);

    }

  }

  close(fd);

  CLEAR_HEAD(pa->ai_qs.deps);

  if (old_version != ARRAY_QS_STRUCT_VERSION)
  {
    /* resave the array struct if the version on disk is older than the current */
    array_save(pa);
  }

  /* link the struct into the servers list of job arrays */
  append_link(&svr_jobarrays, &pa->all_arrays, (void*)pa);

  *new_pa = pa;

  return PBSE_NONE;

  }
Exemple #27
0
int status_node(

  struct pbsnode       *pnode,    /* ptr to node receiving status query */
  struct batch_request *preq,
  int                  *bad,      /* O */
  tlist_head           *pstathd)  /* head of list to append status to  */

  {
  int                rc = 0;

  struct brp_status *pstat;
  svrattrl          *pal;

  if ((preq->rq_perm & ATR_DFLAG_RDACC) == 0)
    {
    return(PBSE_PERM);
    }

  /* allocate status sub-structure and fill in header portion */

  pstat = (struct brp_status *)calloc(1, sizeof(struct brp_status));

  if (pstat == NULL)
    {
    return(PBSE_SYSTEM);
    }

  pstat->brp_objtype = MGR_OBJ_NODE;

  strncpy(pstat->brp_objname, pnode->nd_name, sizeof(pstat->brp_objname)-1);

  CLEAR_LINK(pstat->brp_stlink);
  CLEAR_HEAD(pstat->brp_attr);

  /*add this new brp_status structure to the list hanging off*/
  /*the request's reply substructure                         */

  append_link(pstathd, &pstat->brp_stlink, pstat);

  /*point to the list of node-attributes about which we want status*/
  /*hang that status information from the brp_attr field for this  */
  /*brp_status structure                                           */

  *bad = 0;                                    /*global variable*/

  if (preq->rq_ind.rq_status.rq_attr.ll_struct != NULL)
    pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);
  else
    pal = NULL;

  rc = status_nodeattrib(
         pal,
         node_attr_def,
         pnode,
         ND_ATR_LAST,
         preq->rq_perm,
         &pstat->brp_attr,
         bad);

  return(rc);
  }  /* END status_node() */
Exemple #28
0
int setup_array_struct(job *pjob)
  {
  job_array *pa;

  /* struct work_task *wt; */
  array_request_node *rn;
  int bad_token_count;
  int array_size;
  int rc;

  /* setup a link to this job array in the servers all_arrays list */
  pa = (job_array *)calloc(1,sizeof(job_array));

  pa->ai_qs.struct_version = ARRAY_QS_STRUCT_VERSION;
  
  pa->template_job = pjob;

  /*pa->ai_qs.array_size  = pjob->ji_wattr[(int)JOB_ATR_job_array_size].at_val.at_long;*/

  strcpy(pa->ai_qs.parent_id, pjob->ji_qs.ji_jobid);
  strcpy(pa->ai_qs.fileprefix, pjob->ji_qs.ji_fileprefix);
  strncpy(pa->ai_qs.owner, pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str, PBS_MAXUSER + PBS_MAXSERVERNAME + 2);
  strncpy(pa->ai_qs.submit_host, get_variable(pjob, pbs_o_host), PBS_MAXSERVERNAME);

  pa->ai_qs.num_cloned = 0;
  CLEAR_LINK(pa->all_arrays);
  CLEAR_HEAD(pa->request_tokens);
  append_link(&svr_jobarrays, &pa->all_arrays, (void*)pa);

 if (job_save(pjob, SAVEJOB_FULL, 0) != 0)
    {
    job_purge(pjob);


    if (LOGLEVEL >= 6)
      {
      log_record(
        PBSEVENT_JOB,
        PBS_EVENTCLASS_JOB,
        (pjob != NULL) ? pjob->ji_qs.ji_jobid : "NULL",
        "cannot save job");
      }

    return 1;
    }

  if ((rc = set_slot_limit(pjob->ji_wattr[JOB_ATR_job_array_request].at_val.at_str, pa)))
    {
    array_delete(pa);

    snprintf(log_buffer,sizeof(log_buffer),
      "Array %s requested a slot limit above the max limit %ld, rejecting\n",
      pa->ai_qs.parent_id,
      server.sv_attr[SRV_ATR_MaxSlotLimit].at_val.at_long);
    log_event(PBSEVENT_SYSTEM,
      PBS_EVENTCLASS_JOB,
      pa->ai_qs.parent_id,
      log_buffer);

    return(INVALID_SLOT_LIMIT);
    }

  pa->ai_qs.jobs_running = 0;
  pa->ai_qs.num_started = 0;
  pa->ai_qs.num_failed = 0;
  pa->ai_qs.num_successful = 0;
  
  bad_token_count =

    parse_array_request(pjob->ji_wattr[JOB_ATR_job_array_request].at_val.at_str,
                        &(pa->request_tokens));

  /* get the number of elements that should be allocated in the array */
  rn = (array_request_node *)GET_NEXT(pa->request_tokens);
  array_size = 0;
  pa->ai_qs.num_jobs = 0;
  while (rn != NULL) 
    {
    if (rn->end > array_size)
      array_size = rn->end;
    /* calculate the actual number of jobs (different from array size) */
    pa->ai_qs.num_jobs += rn->end - rn->start + 1;

    rn = (array_request_node *)GET_NEXT(rn->request_tokens_link);
    }

  /* size of array is the biggest index + 1 */
  array_size++; 

  if (server.sv_attr[SRV_ATR_MaxArraySize].at_flags & ATR_VFLAG_SET)
    {
    int max_array_size = server.sv_attr[SRV_ATR_MaxArraySize].at_val.at_long;
    if (max_array_size < pa->ai_qs.num_jobs)
      {
      array_delete(pa);

      return(ARRAY_TOO_LARGE);
      }
    }

  /* initialize the array */
  pa->jobs = malloc(array_size * sizeof(job *));
  memset(pa->jobs,0,array_size * sizeof(job *));

  /* remember array_size */
  pa->ai_qs.array_size = array_size;

  CLEAR_HEAD(pa->ai_qs.deps);

  array_save(pa);

  if (bad_token_count > 0)
    {
    array_delete(pa);
    return 2;
    }

  return 0;

  }
Exemple #29
0
static void req_stat_job_step2(

  struct stat_cntl *cntl)  /* I/O (free'd on return) */

  {
  svrattrl              *pal;
  job                   *pjob = NULL;

  struct batch_request  *preq;
  struct batch_reply    *preply;
  int                    rc = 0;
  enum TJobStatTypeEnum  type;
  pbs_queue             *pque = NULL;
  int                    exec_only = 0;

  int                    bad = 0;
  long                   DTime;  /* delta time - only report full pbs_attribute list if J->MTime > DTime */
  static svrattrl       *dpal = NULL;
  int                    job_array_index = 0;
  job_array             *pa = NULL;
  char                   log_buf[LOCAL_LOG_BUF_SIZE];
  all_jobs_iterator      *iter;

  preq   = cntl->sc_origrq;
  type   = (enum TJobStatTypeEnum)cntl->sc_type;
  preply = &preq->rq_reply;

  /* See pbs_server_attributes(1B) for details on "poll_jobs" behaviour */

  if (dpal == NULL)
    {
    /* build 'delta' pbs_attribute list */

    svrattrl *tpal;

    tlist_head dalist;

    int aindex;

    int atrlist[] =
      {
      JOB_ATR_jobname,
      JOB_ATR_resc_used,
      JOB_ATR_LAST
      };

    CLEAR_LINK(dalist);

    for (aindex = 0;atrlist[aindex] != JOB_ATR_LAST;aindex++)
      {
      if ((tpal = attrlist_create("", "", 23)) == NULL)
        {
        return;
        }

      tpal->al_valln = atrlist[aindex];

      if (dpal == NULL)
        dpal = tpal;

      append_link(&dalist, &tpal->al_link, tpal);
      }
    }  /* END if (dpal == NULL) */

  if (type == tjstArray)
    {
    pa = get_array(preq->rq_ind.rq_status.rq_id);

    if (pa == NULL)
      {
      req_reject(PBSE_UNKARRAYID, 0, preq, NULL, "unable to find array");
      return;
      }
    }

  {
  all_jobs *ajptr = NULL;

  if (type == tjstQueue)
    ajptr = cntl->sc_pque->qu_jobs;

  else if (type == tjstSummarizeArraysQueue)
    ajptr = cntl->sc_pque->qu_jobs_array_sum;

  else if (type == tjstSummarizeArraysServer)
    ajptr = &array_summary;

  else
    ajptr = &alljobs;

  ajptr->lock();
  iter = ajptr->get_iterator();
  ajptr->unlock();
  }

  /*
   * now ready for part 3, building the status reply,
   * loop through again
   */

  if ((type == tjstSummarizeArraysQueue) || 
      (type == tjstSummarizeArraysServer))
    {
    /* No array can be owned for these options */
    update_array_statuses();
    }


  if (type == tjstJob)
    pjob = svr_find_job(preq->rq_ind.rq_status.rq_id, FALSE);

  else if (type == tjstQueue)
    pjob = next_job(cntl->sc_pque->qu_jobs,iter);

  else if (type == tjstSummarizeArraysQueue)
    pjob = next_job(cntl->sc_pque->qu_jobs_array_sum,iter);

  else if (type == tjstSummarizeArraysServer)
    pjob = next_job(&array_summary,iter);

  else if (type == tjstArray)
    {
    job_array_index = -1;
    pjob = NULL;
    /* increment job_array_index until we find a non-null pointer or hit the end */
    while (++job_array_index < pa->ai_qs.array_size)
      {
      if (pa->job_ids[job_array_index] != NULL)
        {
        if ((pjob = svr_find_job(pa->job_ids[job_array_index], FALSE)) != NULL)
          {
          break;
          }
        }
      }
    }
  else
    pjob = next_job(&alljobs,iter);

  DTime = 0;

  if (preq->rq_extend != NULL)
    {
    char *ptr;

    /* FORMAT:  { EXECQONLY | DELTA:<EPOCHTIME> } */

    if (strstr(preq->rq_extend, EXECQUEONLY))
      exec_only = 1;

    ptr = strstr(preq->rq_extend, "DELTA:");

    if (ptr != NULL)
      {
      ptr += strlen("delta:");

      DTime = strtol(ptr, NULL, 10);
      }
    }

  if ((type == tjstTruncatedServer) || 
      (type == tjstTruncatedQueue))
    {
    long sentJobCounter;
    long qjcounter;
    long qmaxreport;
    all_queues_iterator *iter = NULL;

    svr_queues.lock();
    iter = svr_queues.get_iterator();
    svr_queues.unlock();

    /* loop through all queues */
    while ((pque = next_queue(&svr_queues,iter)) != NULL)
      {
      qjcounter = 0;

      if ((exec_only == 1) &&
          (pque->qu_qs.qu_type != QTYPE_Execution))
        {
        /* ignore routing queues */
        unlock_queue(pque, __func__, "ignore queue", LOGLEVEL);
        continue;
        }

      if (((pque->qu_attr[QA_ATR_MaxReport].at_flags & ATR_VFLAG_SET) != 0) &&
          (pque->qu_attr[QA_ATR_MaxReport].at_val.at_long >= 0))
        {
        qmaxreport = pque->qu_attr[QA_ATR_MaxReport].at_val.at_long;
        }
      else
        {
        qmaxreport = TMAX_JOB;
        }

      if (LOGLEVEL >= 5)
        {
        sprintf(log_buf,"giving scheduler up to %ld idle jobs in queue %s\n",
          qmaxreport,
          pque->qu_qs.qu_name);

        log_event(PBSEVENT_SYSTEM,PBS_EVENTCLASS_QUEUE,pque->qu_qs.qu_name,log_buf);
        }

      sentJobCounter = 0;

      /* loop through jobs in queue */
      if (pjob != NULL)
        unlock_ji_mutex(pjob, __func__, "5", LOGLEVEL);

      all_jobs_iterator *jobiter = NULL;
      pque->qu_jobs->lock();
      jobiter = pque->qu_jobs->get_iterator();
      pque->qu_jobs->unlock();

      while ((pjob = next_job(pque->qu_jobs,jobiter)) != NULL)
        {
        if ((qjcounter >= qmaxreport) &&
            (pjob->ji_qs.ji_state == JOB_STATE_QUEUED))
          {
          /* max_report of queued jobs reached for queue */
          unlock_ji_mutex(pjob, __func__, "6", LOGLEVEL);

          continue;
          }

        pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);

        rc = status_job(
               pjob,
               preq,
               (pjob->ji_wattr[JOB_ATR_mtime].at_val.at_long >= DTime) ? pal : dpal,
               &preply->brp_un.brp_status,
               &bad);

        if ((rc != 0) && (rc != PBSE_PERM))
          {
          req_reject(rc, bad, preq, NULL, NULL);

          unlock_ji_mutex(pjob, __func__, "7", LOGLEVEL);
          unlock_queue(pque, __func__, "perm", LOGLEVEL);

          delete iter;

          return;
          }

        sentJobCounter++;

        if (pjob->ji_qs.ji_state == JOB_STATE_QUEUED)
          qjcounter++;

        unlock_ji_mutex(pjob, __func__, "8", LOGLEVEL);
        }    /* END foreach (pjob from pque) */

      if (LOGLEVEL >= 5)
        {
        sprintf(log_buf,"sent scheduler %ld total jobs for queue %s\n",
          sentJobCounter,
          pque->qu_qs.qu_name);

        log_event(PBSEVENT_SYSTEM,PBS_EVENTCLASS_QUEUE,pque->qu_qs.qu_name,log_buf);
        }
    
      unlock_queue(pque, __func__, "end while", LOGLEVEL);
      }      /* END for (pque) */

    reply_send_svr(preq);

    delete iter;

    return;
    } /* END if ((type == tjstTruncatedServer) || ...) */

  while (pjob != NULL)
    {
    /* go ahead and build the status reply for this job */

    if (exec_only)
      {
      if (cntl->sc_pque != NULL)
        {
        if (cntl->sc_pque->qu_qs.qu_type != QTYPE_Execution)
          goto nextjob;
        }
      else
        {
        if (pa != NULL)
          pthread_mutex_unlock(pa->ai_mutex);
        pque = get_jobs_queue(&pjob);
        if (pa != NULL)
          pthread_mutex_lock(pa->ai_mutex);

        if ((pjob == NULL) ||
            (pque == NULL))
          goto nextjob;
        
        mutex_mgr pque_mutex = mutex_mgr(pque->qu_mutex, true);
        if (pque->qu_qs.qu_type != QTYPE_Execution)
          {
          goto nextjob;
          }
        }
      }

    pal = (svrattrl *)GET_NEXT(preq->rq_ind.rq_status.rq_attr);

    rc = status_job(
           pjob,
           preq,
           pal,
           &preply->brp_un.brp_status,
           &bad);

    if ((rc != 0) && 
        (rc != PBSE_PERM))
      {
      if (pa != NULL)
        {
        unlock_ai_mutex(pa, __func__, "1", LOGLEVEL);
        }

      unlock_ji_mutex(pjob, __func__, "9", LOGLEVEL);

      req_reject(rc, bad, preq, NULL, NULL);

      delete iter;

      return;
      }

    /* get next job */

nextjob:

    if (pjob != NULL)
      unlock_ji_mutex(pjob, __func__, "10", LOGLEVEL);

    if (type == tjstJob)
      break;

    if (type == tjstQueue)
      pjob = next_job(cntl->sc_pque->qu_jobs,iter);
    else if (type == tjstSummarizeArraysQueue)
      pjob = next_job(cntl->sc_pque->qu_jobs_array_sum,iter);
    else if (type == tjstSummarizeArraysServer)
      pjob = next_job(&array_summary,iter);
    else if (type == tjstArray)
      {
      pjob = NULL;
      /* increment job_array_index until we find a non-null pointer or hit the end */
      while (++job_array_index < pa->ai_qs.array_size)
        {
        if (pa->job_ids[job_array_index] != NULL)
          {
          if ((pjob = svr_find_job(pa->job_ids[job_array_index], FALSE)) != NULL)
            {
            break;
            }
          }
        }
      }
    else
      pjob = next_job(&alljobs,iter);

    rc = 0;
    }  /* END while (pjob != NULL) */

  delete iter;

  if (pa != NULL)
    {
    unlock_ai_mutex(pa, __func__, "1", LOGLEVEL);
    }
 
  reply_send_svr(preq);

  if (LOGLEVEL >= 7)
    {
    log_event(PBSEVENT_SYSTEM,
      PBS_EVENTCLASS_JOB,
      "req_statjob",
      "Successfully returned the status of queued jobs\n");
    }

  return;
  }  /* END req_stat_job_step2() */
Exemple #30
0
static int parse_array_request(char *request, tlist_head *tl)
  {
  char *temp_str;
  int num_tokens;
  char **tokens;
  int i;
  int j;
  int num_elements;
  int start;
  int end;
  int num_bad_tokens;
  int searching;
  array_request_node *rn;
  array_request_node *rn2;

  temp_str = strdup(request);
  num_tokens = array_request_token_count(request);
  num_bad_tokens = 0;

  tokens = (char**)malloc(sizeof(char*) * num_tokens);
  j = num_tokens - 1;
  /* start from back and scan backwards setting pointers to tokens and changing ',' to '\0' */

  for (i = strlen(temp_str) - 1; i >= 0; i--)
    {

    if (temp_str[i] == ',')
      {
      tokens[j--] = &temp_str[i+1];
      temp_str[i] = '\0';
      }
    else if (i == 0)
      {
      tokens[0] = temp_str;
      }
    }


  for (i = 0; i < num_tokens; i++)
    {
    num_elements = array_request_parse_token(tokens[i], &start, &end);

    if (num_elements == 0)
      {
      num_bad_tokens++;
      }
    else
      {
      rn = (array_request_node*)malloc(sizeof(array_request_node));
      rn->start = start;
      rn->end = end;
      CLEAR_LINK(rn->request_tokens_link);

      rn2 = GET_NEXT(*tl);
      searching = TRUE;

      while (searching)
        {

        if (rn2 == NULL)
          {
          append_link(tl, &rn->request_tokens_link, (void*)rn);
          searching = FALSE;
          }
        else if (rn->start < rn2->start)
          {
          insert_link(&rn2->request_tokens_link, &rn->request_tokens_link, (void*)rn,
                      LINK_INSET_BEFORE);
          searching = FALSE;
          }
        else
          {
          rn2 = GET_NEXT(rn2->request_tokens_link);
          }

        }

      rn2 = GET_PRIOR(rn->request_tokens_link);

      if (rn2 != NULL && rn2->end >= rn->start)
        {
        num_bad_tokens++;
        }

      rn2 = GET_NEXT(rn->request_tokens_link);

      if (rn2 != NULL && rn2->start <= rn->end)
        {
        num_bad_tokens++;
        }

      }
    }

  free(tokens);

  free(temp_str);

  return num_bad_tokens;
  }