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() */
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); }
/** * @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); }
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; }
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() */
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); }
/** * @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() */
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); }
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() */
/** * * @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); }
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() */
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); }
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); }
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); }
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); }
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); }
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() */
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() */
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() */
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() */
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); }
/* 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; }
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() */
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; }
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() */
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; }