Esempio n. 1
0
END_TEST

START_TEST(svr_enquejob_test)
  {
  struct job test_job;
  int result = PBSE_NONE;

  /*initialize_globals*/
  server.sv_qs_mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
  server.sv_attr_mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));
  server.sv_jobstates_mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t));

  pthread_mutex_init(server.sv_qs_mutex,NULL);
  pthread_mutex_init(server.sv_attr_mutex,NULL);
  pthread_mutex_init(server.sv_jobstates_mutex,NULL);

  memset(&test_job, 0, sizeof(test_job));

  result = svr_enquejob(NULL, 0, 0, false);
  fail_unless(result != PBSE_NONE, "NULL input pointer fail");

  result = svr_enquejob(&test_job, 0, 0, false);
  /*Need more complicated mocking in order to have other result than PBSE_JOBNOTFOUND*/
  fail_unless(result == PBSE_JOBNOTFOUND, "svr_enquejob fail: %d", result);

  }
Esempio n. 2
0
static void close_quejob(

  int sfds)

  {
  job *pjob;
  job *npjob;

  pjob = (job *)GET_NEXT(svr_newjobs);

  while (pjob != NULL)
    {
    npjob = GET_NEXT(pjob->ji_alljobs);

    if (pjob->ji_qs.ji_un.ji_newt.ji_fromsock == sfds)
      {
      if (pjob->ji_qs.ji_substate == JOB_SUBSTATE_TRANSICM)
        {

#ifndef PBS_MOM

        if (pjob->ji_qs.ji_svrflags & JOB_SVFLG_HERE)
          {
          /*
           * the job was being created here for the first time
           * go ahead and enqueue it as QUEUED; otherwise, hold
           * it here as TRANSICM until we hear from the sending
           * server again to commit.
           */

          delete_link(&pjob->ji_alljobs);

          pjob->ji_qs.ji_state = JOB_STATE_QUEUED;
          pjob->ji_qs.ji_substate = JOB_SUBSTATE_QUEUED;

          if (svr_enquejob(pjob))
            job_abt(&pjob, msg_err_noqueue);
          }

#endif /* PBS_MOM */

        }
      else
        {
        /* else delete the job */

        delete_link(&pjob->ji_alljobs);

        job_purge(pjob);
        }

      break;
      }  /* END if (..) */

    pjob = npjob;
    }

  return;
  }  /* END close_quejob() */
Esempio n. 3
0
int close_quejob_by_jobid(
    
  char *job_id)

  {
  int    rc = PBSE_NONE;
  job   *pjob = NULL;

  if (LOGLEVEL >= 10)
    {
    LOG_EVENT(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, job_id);
    }

  if ((pjob = svr_find_job(job_id, FALSE)) == NULL)
    {
    rc = PBSE_JOBNOTFOUND;
    return(rc);
    }

  mutex_mgr pjob_mutex = mutex_mgr(pjob->ji_mutex, true);
  if (pjob->ji_qs.ji_substate != JOB_SUBSTATE_TRANSICM)
    {
    remove_job(&newjobs,pjob);
    svr_job_purge(pjob);
    pjob = NULL;
    }
  else if (pjob->ji_qs.ji_svrflags & JOB_SVFLG_HERE)
    {
    remove_job(&newjobs,pjob);
    pjob->ji_qs.ji_state = JOB_STATE_QUEUED;
    pjob->ji_qs.ji_substate = JOB_SUBSTATE_QUEUED;
    rc = svr_enquejob(pjob, FALSE, -1, false);

    if ((rc == PBSE_JOBNOTFOUND) ||
        (rc == PBSE_JOB_RECYCLED))
      {
      pjob = NULL;
      }
    else if (rc != PBSE_NONE)
      {
      job_abt(&pjob, msg_err_noqueue);
      pjob = NULL;
      }
    }

  if (pjob == NULL)
    pjob_mutex.set_lock_on_exit(false);

  return(rc);
  } /* close_quejob_by_jobid() */
Esempio n. 4
0
int req_orderjob(

  struct batch_request *vp) /* I */

  {
  job                  *pjob;
  job                  *pjob1;
  job                  *pjob2;
  int                   rank;
  int                   rc = 0;
  char                  tmpqn[PBS_MAXQUEUENAME+1];
  struct batch_request *req = (struct batch_request *)vp;
  char                  log_buf[LOCAL_LOG_BUF_SIZE];
  pbs_queue            *pque1;
  pbs_queue            *pque2;

  if ((pjob1 = chk_job_request(req->rq_ind.rq_move.rq_jid, req)) == NULL)
    {
    return(PBSE_NONE);
    }

  mutex_mgr job1_mutex(pjob1->ji_mutex, true);

  if ((pjob2 = chk_job_request(req->rq_ind.rq_move.rq_destin, req)) == NULL)
    {
    return(PBSE_NONE);
    }

  mutex_mgr job2_mutex(pjob2->ji_mutex, true);

  if (((pjob = pjob1)->ji_qs.ji_state == JOB_STATE_RUNNING) ||
      ((pjob = pjob2)->ji_qs.ji_state == JOB_STATE_RUNNING))
    {
#ifndef NDEBUG
    sprintf(log_buf, "%s %d",
            pbse_to_txt(PBSE_BADSTATE),
            pjob->ji_qs.ji_state);

    strcat(log_buf, __func__);

    log_event(
      PBSEVENT_DEBUG,
      PBS_EVENTCLASS_JOB,
      pjob->ji_qs.ji_jobid,
      log_buf);
#endif /* NDEBUG */

    req_reject(PBSE_BADSTATE, 0, req, NULL, NULL);

    return(PBSE_NONE);
    }
  else if ((pjob1->ji_qhdr == NULL) || (pjob2->ji_qhdr == NULL))
    {
    req_reject(PBSE_BADSTATE, 0, req, NULL, "One of the jobs does not have a queue");
    return(PBSE_NONE);
    }
  else if (pjob1->ji_qhdr != pjob2->ji_qhdr)
    {
    /* jobs are in different queues */
    int ok = FALSE;

    if ((pque2 = get_jobs_queue(&pjob2)) == NULL)
      {
      rc = PBSE_BADSTATE;
      job2_mutex.set_lock_on_exit(false);
      }
    else
      {
      mutex_mgr pque2_mutex = mutex_mgr(pque2->qu_mutex, true);
      if ((rc = svr_chkque(pjob1, pque2, get_variable(pjob1, pbs_o_host), MOVE_TYPE_Order, NULL)) == PBSE_NONE)
        {
        pque2_mutex.unlock();

        if ((pque1 = get_jobs_queue(&pjob1)) == NULL)
          {
          rc = PBSE_BADSTATE;
          job1_mutex.set_lock_on_exit(false);
          }
        else if (pjob1 != NULL)
          {
          mutex_mgr pque1_mutex = mutex_mgr(pque1->qu_mutex, true);
          if ((rc = svr_chkque(pjob2, pque1, get_variable(pjob2, pbs_o_host), MOVE_TYPE_Order, NULL)) == PBSE_NONE)
            {
            ok = TRUE;
            }
          }
        }
      }

    if (ok == FALSE)
      {
      req_reject(rc, 0, req, NULL, NULL);

      return(PBSE_NONE);
      }
    }

  /* now swap the order of the two jobs in the queue lists */
  rank = pjob1->ji_wattr[JOB_ATR_qrank].at_val.at_long;

  pjob1->ji_wattr[JOB_ATR_qrank].at_val.at_long =
    pjob2->ji_wattr[JOB_ATR_qrank].at_val.at_long;

  pjob2->ji_wattr[JOB_ATR_qrank].at_val.at_long = rank;

  if (pjob1->ji_qhdr != pjob2->ji_qhdr)
    {
    strcpy(tmpqn, pjob1->ji_qs.ji_queue);
    strcpy(pjob1->ji_qs.ji_queue, pjob2->ji_qs.ji_queue);
    strcpy(pjob2->ji_qs.ji_queue, tmpqn);

    svr_dequejob(pjob1, FALSE);
    svr_dequejob(pjob2, FALSE);

    if (svr_enquejob(pjob1, FALSE, -1) == PBSE_JOB_RECYCLED)
      {
      pjob1 = NULL;
      job1_mutex.set_lock_on_exit(false);
      }

    if (svr_enquejob(pjob2, FALSE, -1) == PBSE_JOB_RECYCLED)
      {
      pjob2 = NULL;
      job2_mutex.set_lock_on_exit(false);
      }
    }
  else
    {
    if ((pque1 = get_jobs_queue(&pjob1)) != NULL)
      {
      mutex_mgr pque1_mutex = mutex_mgr(pque1->qu_mutex, true);
      swap_jobs(pque1->qu_jobs,pjob1,pjob2);
      swap_jobs(NULL,pjob1,pjob2);
      }
    }

  /* need to update disk copy of both jobs to save new order */
  if (pjob1 != NULL)
    {
    job_save(pjob1, SAVEJOB_FULL, 0);
    }

  if (pjob2 != NULL)
    {
    job_save(pjob2, SAVEJOB_FULL, 0);
    }

  /* SUCCESS */
  reply_ack(req);

  return(PBSE_NONE);
  }  /* END req_orderjob() */
Esempio n. 5
0
static int local_move(

  job                  *jobp,
  struct batch_request *req)

  {
  char   *id = "local_move";
  pbs_queue *qp;
  char   *destination = jobp->ji_qs.ji_destin;
  int    mtype;

  /* search for destination queue */

  if ((qp = find_queuebyname(destination)) == NULL)
    {
    sprintf(log_buffer, "queue %s does not exist\n",
            destination);

    log_err(-1, id, log_buffer);

    pbs_errno = PBSE_UNKQUE;

    return(ROUTE_PERM_FAILURE);
    }

  /*
   * if being moved at specific request of administrator, then
   * checks on queue availability, etc. are skipped;
   * otherwise all checks are enforced.
   */

  if (req == 0)
    {
    mtype = MOVE_TYPE_Route; /* route */
    }
  else if (req->rq_perm & (ATR_DFLAG_MGRD | ATR_DFLAG_MGWR))
    {
    mtype = MOVE_TYPE_MgrMv; /* privileged move */
    }
  else
    {
    mtype = MOVE_TYPE_Move; /* non-privileged move */
    }

  if ((pbs_errno = svr_chkque(
                     jobp,
                     qp,
                     get_variable(jobp, pbs_o_host), mtype, NULL)))
    {
    /* should this queue be retried? */

    return(should_retry_route(pbs_errno));
    }

  /* dequeue job from present queue, update destination and */
  /* queue_rank for new queue and enqueue into destination  */

  svr_dequejob(jobp);

  strcpy(jobp->ji_qs.ji_queue, destination);

  jobp->ji_wattr[JOB_ATR_qrank].at_val.at_long = ++queue_rank;

  pbs_errno = svr_enquejob(jobp);

  if (pbs_errno != 0)
    {
    return(ROUTE_PERM_FAILURE); /* should never ever get here */
    }

  jobp->ji_lastdest = 0; /* reset in case of another route */

  job_save(jobp, SAVEJOB_FULL);

  return(ROUTE_SUCCESS);
  }  /* END local_move() */
Esempio n. 6
0
void
req_orderjob(struct batch_request *req)
{
	int      jt1, jt2;            /* job type */
	job	*pjob;
	job	*pjob1;
	job	*pjob2;
	long	 rank;
	int	 rc;
	char	 tmpqn[PBS_MAXQUEUENAME+1];

	if ((pjob1=chk_job_request(req->rq_ind.rq_move.rq_jid, req, &jt1)) == NULL)
		return;
	if ((pjob2=chk_job_request(req->rq_ind.rq_move.rq_destin, req, &jt2)) == NULL)
		return;
	if ((jt1 == IS_ARRAY_Single) || (jt2 == IS_ARRAY_Single) ||
		(jt1 == IS_ARRAY_Range)  || (jt2 == IS_ARRAY_Range)) {
		/* can only move regular or Array Job, not Subjobs */
		req_reject(PBSE_IVALREQ, 0, req);
		return;
	}

	if (((pjob = pjob1)->ji_qs.ji_state == JOB_STATE_RUNNING) ||
		((pjob = pjob2)->ji_qs.ji_state == JOB_STATE_RUNNING) ||
		((pjob = pjob1)->ji_qs.ji_state == JOB_STATE_BEGUN)   ||
		((pjob = pjob2)->ji_qs.ji_state == JOB_STATE_BEGUN)) {
#ifndef NDEBUG
		(void)sprintf(log_buffer, "(%s) %s, state=%d",
			__func__, msg_badstate, pjob->ji_qs.ji_state);
		log_event(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, LOG_DEBUG,
			pjob->ji_qs.ji_jobid, log_buffer);
#endif	/* NDEBUG */
		req_reject(PBSE_BADSTATE, 0, req);
		return;
	} else if (pjob1->ji_qhdr != pjob2->ji_qhdr) {

		/* Jobs are in different queues */

		if ((rc = svr_chkque(pjob1, pjob2->ji_qhdr,
			get_hostPart(pjob1->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str),
			MOVE_TYPE_Order)) ||
			(rc = svr_chkque(pjob2, pjob1->ji_qhdr,
			get_hostPart(pjob2->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str),
			MOVE_TYPE_Order))) {
			req_reject(rc, 0, req);
			return;
		}
	}

	/* now swap the order of the two jobs in the queue lists */

	rank = pjob1->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long;
	pjob1->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long =
		pjob2->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long;
	pjob1->ji_wattr[(int)JOB_ATR_qrank].at_flags |= ATR_VFLAG_MODCACHE;
	pjob2->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long = rank;
	pjob2->ji_wattr[(int)JOB_ATR_qrank].at_flags |= ATR_VFLAG_MODCACHE;

	if (pjob1->ji_qhdr != pjob2->ji_qhdr) {
		(void)strcpy(tmpqn, pjob1->ji_qs.ji_queue);
		(void)strcpy(pjob1->ji_qs.ji_queue, pjob2->ji_qs.ji_queue);
		(void)strcpy(pjob2->ji_qs.ji_queue, tmpqn);
		svr_dequejob(pjob1);
		svr_dequejob(pjob2);
		(void)svr_enquejob(pjob1);
		(void)svr_enquejob(pjob2);

	} else {
		swap_link(&pjob1->ji_jobque,  &pjob2->ji_jobque);
		swap_link(&pjob1->ji_alljobs, &pjob2->ji_alljobs);
	}

	/* need to update disk copy of both jobs to save new order */

	(void)job_save(pjob1, SAVEJOB_FULL);
	(void)job_save(pjob2, SAVEJOB_FULL);

	reply_ack(req);
}
Esempio n. 7
0
/**
 * @brief
 * 		create_subjob - create a Subjob from the parent Array Job
 * 		Certain attributes are changed or left out
 * @param[in]	parent - pointer to parent Job
 * @param[in]	newjid -  new job id
 * @param[in]	rc -  return code
 * @return	pointer to new job
 * @retval  NULL	- error
 */
job *
create_subjob(job *parent, char *newjid, int *rc)
{
	pbs_list_head  attrl;
	int	   i;
	int	   j;
	int	   indx;
	char	  *index;
	attribute_def *pdef;
	attribute *ppar;
	attribute *psub;
	svrattrl  *psatl;
	job 	  *subj;
	long	   eligibletime;
	long	    time_msec;
#ifdef	WIN32
	struct	_timeb	    tval;
#else
	struct timeval	    tval;
#endif


	if ((parent->ji_qs.ji_svrflags & JOB_SVFLG_ArrayJob) == 0) {
		*rc = PBSE_IVALREQ;
		return NULL;	/* parent not an array job */
	}

	/* find and copy the index */

	if ((index = get_index_from_jid(newjid)) == NULL) {
		*rc = PBSE_IVALREQ;
		return NULL;
	}
	if ((indx = subjob_index_to_offset(parent, index)) == -1) {
		*rc = PBSE_UNKJOBID;
		return NULL;
	}
	if (parent->ji_ajtrk->tkm_tbl[indx].trk_status != JOB_STATE_QUEUED) {
		*rc = PBSE_BADSTATE;
		return NULL;
	}

	/*
	 * allocate and clear basic structure
	 * cannot copy job attributes because cannot share strings and other
	 * malloc-ed data,  so copy ji_qs as a whole and then copy the
	 * non-saved items before ji_qs.
	 */

	subj = job_alloc();
	subj->ji_qs = parent->ji_qs;	/* copy the fixed save area */

#ifdef PBS_CRED_GRIDPROXY
	subj->ji_gsscontext  = parent->ji_gsscontext;
#endif
	subj->ji_qhdr     = parent->ji_qhdr;
	subj->ji_resvp    = parent->ji_resvp;
	subj->ji_myResv   = parent->ji_myResv;
	subj->ji_parentaj = parent;
	strcpy(subj->ji_qs.ji_jobid, newjid);	/* replace job id */
	*subj->ji_qs.ji_fileprefix = '\0';
	subj->ji_subjindx = indx;

	/*
	 * now that is all done, copy the required attributes by
	 * encoding and then decoding into the new array.  Then add the
	 * subjob specific attributes.
	 */

	resc_access_perm = ATR_DFLAG_ACCESS;
	CLEAR_HEAD(attrl);
	for (i = 0; attrs_to_copy[i] != JOB_ATR_LAST; i++) {
		j    = (int)attrs_to_copy[i];
		ppar = &parent->ji_wattr[j];
		psub = &subj->ji_wattr[j];
		pdef = &job_attr_def[j];

		if (pdef->at_encode(ppar, &attrl, pdef->at_name, NULL,
			ATR_ENCODE_MOM, &psatl) > 0) {
			for (psatl = (svrattrl *)GET_NEXT(attrl); psatl;
				psatl = ((svrattrl *)GET_NEXT(psatl->al_link))) {
				pdef->at_decode(psub, psatl->al_name, psatl->al_resc,
					psatl->al_value);
			}
			/* carry forward the default bit if set */
			psub->at_flags |= (ppar->at_flags & ATR_VFLAG_DEFLT);
			free_attrlist(&attrl);
		}
	}

	psub = &subj->ji_wattr[(int)JOB_ATR_array_id];
	job_attr_def[(int)JOB_ATR_array_id].at_decode(psub, NULL, NULL,
		parent->ji_qs.ji_jobid);

	psub = &subj->ji_wattr[(int)JOB_ATR_array_index];
	job_attr_def[(int)JOB_ATR_array_index].at_decode(psub, NULL, NULL, index);

	/* Lastly, set or clear a few flags and link in the structure */

	subj->ji_qs.ji_svrflags &= ~JOB_SVFLG_ArrayJob;
	subj->ji_qs.ji_svrflags |=  JOB_SVFLG_SubJob;
	subj->ji_modified = 1;	/* ** will likely take this out ** */

	subj->ji_qs.ji_substate = JOB_SUBSTATE_TRANSICM;
	(void)svr_setjobstate(subj, JOB_STATE_QUEUED, JOB_SUBSTATE_QUEUED);
	subj->ji_wattr[(int)JOB_ATR_state].at_flags    |= ATR_VFLAG_SET;
	subj->ji_wattr[(int)JOB_ATR_substate].at_flags |= ATR_VFLAG_SET;

	/* subjob needs to borrow eligible time from parent job array.
	 * expecting only to accrue eligible_time and nothing else.
	 */
	if (server.sv_attr[(int)SRV_ATR_EligibleTimeEnable].at_val.at_long == 1) {

		eligibletime = parent->ji_wattr[(int)JOB_ATR_eligible_time].at_val.at_long;

		if (parent->ji_wattr[(int)JOB_ATR_accrue_type].at_val.at_long == JOB_ELIGIBLE)
			eligibletime += subj->ji_wattr[(int)JOB_ATR_sample_starttime].at_val.at_long - parent->ji_wattr[(int)JOB_ATR_sample_starttime].at_val.at_long;

		subj->ji_wattr[(int)JOB_ATR_eligible_time].at_val.at_long = eligibletime;
		subj->ji_wattr[(int)JOB_ATR_eligible_time].at_flags |= ATR_VFLAG_MODIFY | ATR_VFLAG_MODCACHE;

	}
#ifdef WIN32
	_ftime_s(&tval);
	time_msec = (tval.time * 1000L) + tval.millitm;
#else
	gettimeofday(&tval, NULL);
	time_msec = (tval.tv_sec * 1000L) + (tval.tv_usec/1000L);
#endif
	/* set the queue rank attribute */
	subj->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long = time_msec;
	subj->ji_wattr[(int)JOB_ATR_qrank].at_flags |= ATR_VFLAG_SET|ATR_VFLAG_MODCACHE;
	if (svr_enquejob(subj) != 0) {
		job_purge(subj);
		*rc = PBSE_IVALREQ;
		return NULL;
	}
	*rc = PBSE_NONE;
	return subj;
}
Esempio n. 8
0
void req_orderjob(

  struct batch_request *req)  /* I */

  {
#ifndef NDEBUG
  char *id = "req_orderjob";
#endif
  job *pjob;
  job *pjob1;
  job *pjob2;
  int  rank;
  int  rc;
  char  tmpqn[PBS_MAXQUEUENAME+1];

  if ((pjob1 = chk_job_request(req->rq_ind.rq_move.rq_jid, req)) == NULL)
    {
    return;
    }

  if ((pjob2 = chk_job_request(req->rq_ind.rq_move.rq_destin, req)) == NULL)
    {
    return;
    }

  if (((pjob = pjob1)->ji_qs.ji_state == JOB_STATE_RUNNING) ||
      ((pjob = pjob2)->ji_qs.ji_state == JOB_STATE_RUNNING))
    {
#ifndef NDEBUG
    sprintf(log_buffer, "%s %d",
            pbse_to_txt(PBSE_BADSTATE),
            pjob->ji_qs.ji_state);

    strcat(log_buffer, id);

    log_event(
      PBSEVENT_DEBUG,
      PBS_EVENTCLASS_JOB,
      pjob->ji_qs.ji_jobid,
      log_buffer);
#endif /* NDEBUG */

    req_reject(PBSE_BADSTATE, 0, req, NULL, NULL);

    return;
    }
  else if (pjob1->ji_qhdr != pjob2->ji_qhdr)
    {
    /* jobs are in different queues */

    if ((rc = svr_chkque(
                pjob1,
                pjob2->ji_qhdr,
                get_variable(pjob1, pbs_o_host),
                MOVE_TYPE_Order,
                NULL)) ||
        (rc = svr_chkque(
                pjob2,
                pjob1->ji_qhdr,
                get_variable(pjob2, pbs_o_host),
                MOVE_TYPE_Order,
                NULL)))
      {
      req_reject(rc, 0, req, NULL, NULL);

      return;
      }
    }

  /* now swap the order of the two jobs in the queue lists */

  rank = pjob1->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long;

  pjob1->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long =
    pjob2->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long;

  pjob2->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long = rank;

  if (pjob1->ji_qhdr != pjob2->ji_qhdr)
    {
    (void)strcpy(tmpqn, pjob1->ji_qs.ji_queue);
    (void)strcpy(pjob1->ji_qs.ji_queue, pjob2->ji_qs.ji_queue);
    (void)strcpy(pjob2->ji_qs.ji_queue, tmpqn);
    svr_dequejob(pjob1);
    svr_dequejob(pjob2);
    (void)svr_enquejob(pjob1);
    (void)svr_enquejob(pjob2);

    }
  else
    {
    swap_link(&pjob1->ji_jobque,  &pjob2->ji_jobque);
    swap_link(&pjob1->ji_alljobs, &pjob2->ji_alljobs);
    }

  /* need to update disk copy of both jobs to save new order */

  job_save(pjob1, SAVEJOB_FULL);

  job_save(pjob2, SAVEJOB_FULL);

  reply_ack(req);

  /* SUCCESS */

  return;
  }  /* END req_orderjob() */
Esempio n. 9
0
int local_move(

  job                  *pjob,
  int                  *my_err,
  struct batch_request *req)

  {
  pbs_queue *dest_que = NULL;
  char      *destination = pjob->ji_qs.ji_destin;
  int        mtype;
  char       log_buf[LOCAL_LOG_BUF_SIZE];
  char       job_id[PBS_MAXSVRJOBID+1];
  int        rc;
  bool       reservation = false;

  /* Sometimes multiple threads are trying to route the same job. Protect against this
   * by making sure that the destionation queue and the current queue are different. 
   * If they are the same then consider it done correctly */
  if (!strcmp(pjob->ji_qs.ji_queue, pjob->ji_qs.ji_destin))
    return(PBSE_NONE);

  if (LOGLEVEL >= 8)
    {
    sprintf(log_buf, "%s", pjob->ji_qs.ji_jobid);
    log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, log_buf);
    }

  /*
   * if being moved at specific request of administrator, then
   * checks on queue availability, etc. are skipped;
   * otherwise all checks are enforced.
   */
  if (req == 0)
    {
    mtype = MOVE_TYPE_Route; /* route */
    }
  else if (req->rq_perm & (ATR_DFLAG_MGRD | ATR_DFLAG_MGWR))
    {
    mtype = MOVE_TYPE_MgrMv; /* privileged move */
    }
  else
    {
    mtype = MOVE_TYPE_Move; /* non-privileged move */
    }

  strcpy(job_id, pjob->ji_qs.ji_jobid);
  unlock_ji_mutex(pjob, __func__, NULL, LOGLEVEL);

  dest_que = find_queuebyname(destination);
  if (dest_que == NULL)
    {
    /* this should never happen */
    sprintf(log_buf, "queue %s does not exist\n", pjob->ji_qs.ji_queue);
    log_err(-1, __func__, log_buf);

    *my_err = PBSE_UNKQUE;
    return(-1);
    }

  mutex_mgr dest_que_mutex = mutex_mgr(dest_que->qu_mutex, true);
  if ((pjob = svr_find_job(job_id, TRUE)) == NULL)
    {
    /* job disappeared while locking queue */
    return(PBSE_JOB_RECYCLED);
    }

  /* check the destination */
  if ((*my_err = svr_chkque(pjob, dest_que, get_variable(pjob, pbs_o_host), mtype, NULL)))
    {
    /* should this queue be retried? */
    return(should_retry_route(*my_err));
    }

  reservation = have_reservation(pjob, dest_que);
  /* dequeue job from present queue, update destination and */
  /* queue_rank for new queue and enqueue into destination  */
  dest_que_mutex.unlock();
  rc = svr_dequejob(pjob, FALSE); 
  if (rc)
    return(rc);

  snprintf(pjob->ji_qs.ji_queue, sizeof(pjob->ji_qs.ji_queue), "%s", destination);

  pjob->ji_wattr[JOB_ATR_qrank].at_val.at_long = ++queue_rank;
    
  if ((*my_err = svr_enquejob(pjob, FALSE, NULL, reservation, false)) == PBSE_JOB_RECYCLED)
    return(-1);

  if (*my_err != PBSE_NONE)
    {
    return(-1); /* should never ever get here */
    }

  if (pjob != NULL)
    {
    pjob->ji_lastdest = 0; /* reset in case of another route */
    
    job_save(pjob, SAVEJOB_FULL, 0);
    }

  return(PBSE_NONE);
  }  /* END local_move() */
Esempio n. 10
0
/**
 * @brief
 * 		Move a job to another queue in this Server.
 *
 * @par
 * 		Check the destination to see if it can accept the job.
 * 		If the job can enter the new queue, dequeue from the existing queue and
 * 		enqueue into the new queue
 *
 * @par
 * 		Note - the destination is specified by the queue's name in the
 *		ji_qs.ji_destin element of the job structure.
 *
 * param[in]	jobp	-	pointer to job to move
 * param[in]	req	-	client request from a qmove client, null if a route
 *
 * @return	int
 * @retval  0	: success
 * @retval -1	: permanent failure or rejection, see pbs_errno
 * @retval  1	: failed but try again later
 */
int
local_move(job *jobp, struct batch_request *req)
{
	pbs_queue *qp;
	char	  *destination = jobp->ji_qs.ji_destin;
	int	   mtype;
	attribute *pattr;
	long	newtype = -1;


	/* search for destination queue */
	if ((qp = find_queuebyname(destination)) == NULL) {
		sprintf(log_buffer,
			"queue %s does not exist",
			destination);
		log_err(-1, __func__, log_buffer);
		pbs_errno = PBSE_UNKQUE;
		return -1;
	}

	/*
	 * if being moved at specific request of administrator, then
	 * checks on queue availability, etc. are skipped;
	 * otherwise all checks are enforced.
	 */

	if (req == NULL) {
		mtype = MOVE_TYPE_Route;	/* route */
	} else if (req->rq_perm & (ATR_DFLAG_MGRD | ATR_DFLAG_MGWR)) {
		mtype =	MOVE_TYPE_MgrMv;	/* privileged move */
	} else {
		mtype = MOVE_TYPE_Move;		/* non-privileged move */
	}

	pbs_errno = svr_chkque(jobp, qp,
		get_hostPart(jobp->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str),
		mtype);

	if (pbs_errno) {
		/* should this queue be retried? */
		return (should_retry_route(pbs_errno));
	}

	/* dequeue job from present queue, update destination and	*/
	/* queue_rank for new queue and enqueue into destination	*/

	svr_dequejob(jobp);
	jobp->ji_myResv = NULL;
	strncpy(jobp->ji_qs.ji_queue, qp->qu_qs.qu_name, PBS_MAXQUEUENAME);
	jobp->ji_qs.ji_queue[PBS_MAXQUEUENAME] = '\0';

	jobp->ji_wattr[(int)JOB_ATR_qrank].at_val.at_long = ++queue_rank;
	jobp->ji_wattr[(int)JOB_ATR_qrank].at_flags |= ATR_VFLAG_MODCACHE;

	pattr = &jobp->ji_wattr[(int)JOB_ATR_reserve_ID];
	if (qp->qu_resvp) {

		job_attr_def[(int)JOB_ATR_reserve_ID].at_decode(pattr,
			(char *)0, (char *)0, qp->qu_resvp->ri_qs.ri_resvID);
		jobp->ji_myResv = qp->qu_resvp;
	} else {

		job_attr_def[(int)JOB_ATR_reserve_ID].at_decode(pattr,
			(char *)0, (char *)0, (char*)0);
	}

	if (server.sv_attr[(int)SRV_ATR_EligibleTimeEnable].at_val.at_long == 1) {

		newtype = determine_accruetype(jobp);
		if (newtype == -1)
			/* unable to determine accruetype, set it to NEW */
			(void)update_eligible_time(JOB_INITIAL, jobp);
		else
			/* found suiting accruetype, update to this */
			(void)update_eligible_time(newtype, jobp);

	}


	if ((pbs_errno = svr_enquejob(jobp)) != 0)
		return -1;		/* should never ever get here */

	jobp->ji_lastdest = 0;	/* reset in case of another route */

	(void)job_save(jobp, SAVEJOB_FULL);

	/* If a scheduling cycle is in progress, then this moved job may have
	 * had changes resulting from the move that would impact scheduling or
	 * placement, add job to list of jobs which cannot be run in this cycle.
	 */
	if ((req == NULL || (req->rq_conn != scheduler_sock)) && (scheduler_jobs_stat))
		am_jobs_add(jobp);

	return 0;
}