/* * askey_func - get the $SKEY of an async job */ FUNCTION CODE askey_func ( struct VALUE *strval1, /* in: value containing jobname */ struct CONTXT *context, /* in: TM context */ struct VALUE *strval2, /* out: value containing skey */ struct ERRMSG *(*errmsg) /* out: error message */ ) { struct ACB *a; /* find job in acb list */ TEXT *jobname; if ((*strval1).type != V_STRING) { *errmsg = &er_notstring; return(FAIL); } jobname = (*strval1).uval.strpt; /* jobname */ a = find_job (jobname); if (a == NULL) { *errmsg = &er_nojob; s_copy(jobname, er_nojob.variable); return (FAIL); } inival(strval2); /* set some defaults */ (*strval2).type = V_STRING; (*strval2).uval.strpt = s_save((*a).skey); return (SUCCESS); }
bool Q::reschedule(const string& uid, const long run_at) { JobOption job = find_job(uid); if (job.empty()) return false; update_job_run_at(job.get().uid(), run_at); return true; }
static void process_checkpoint_reply( struct work_task *pwt) { job *pjob; struct batch_request *preq; svr_disconnect(pwt->wt_event); /* close connection to MOM */ preq = pwt->wt_parm1; preq->rq_conn = preq->rq_orgconn; /* restore client socket */ if ((pjob = find_job(preq->rq_ind.rq_manager.rq_objname)) == (job *)0) { LOG_EVENT(PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, preq->rq_ind.rq_manager.rq_objname, msg_postmomnojob); req_reject(PBSE_UNKJOBID, 0, preq, NULL, msg_postmomnojob); } else { /* record that MOM has a checkpoint file */ account_record(PBS_ACCT_CHKPNT, pjob, "Checkpointed"); /* note in accounting file */ reply_ack(preq); } }
/* * restart a job in foreground * input(1) : %JID or PID (char *) */ int restart_fg(char *argv) { int num = 0; int jid = 0; int pid = 0; if (argv == NULL) return 0; if (argv[0] == '%') { if ((jid = atoi(++argv)) != 0) { if (job_lists[jid]) { pid = job_lists[jid]->PID; Kill(pid, SIGKILL); longjmp(restart_buf, 2); } } } else if ((num = atoi(argv)) != 0) { jid = find_job(num); if (jid != 0) { pid = job_lists[jid]->PID; Kill(pid, SIGKILL); longjmp(restart_buf, 2); } } printf("%s: No such process\n", argv); }
static void post_chkpt(struct work_task *ptask) { job *pjob; struct batch_request *preq; preq = (struct batch_request *)ptask->wt_parm1; pjob = find_job(preq->rq_ind.rq_hold.rq_orig.rq_objname); if (!preq || !pjob) return; if (preq->rq_reply.brp_code == 0) { /* checkpointed ok */ if (preq->rq_reply.brp_auxcode) { /* chkpt can be moved */ pjob->ji_qs.ji_svrflags &= ~JOB_SVFLG_CHKPT; pjob->ji_qs.ji_svrflags |= JOB_SVFLG_ChkptMig; pjob->ji_modified = 1; (void)job_save(pjob, SAVEJOB_QUICK); } account_record(PBS_ACCT_CHKPNT, pjob, (char *)0); } else { /* need to try rerun if possible or just abort the job */ if (preq->rq_reply.brp_code != PBSE_CKPBSY) { pjob->ji_qs.ji_svrflags &= ~JOB_SVFLG_CHKPT; pjob->ji_qs.ji_substate = JOB_SUBSTATE_RUNNING; pjob->ji_modified = 1; (void)job_save(pjob, SAVEJOB_QUICK); if (pjob->ji_qs.ji_state == JOB_STATE_RUNNING) rerun_or_kill(pjob, msg_on_shutdown); } } release_req(ptask); }
void ensure_deleted( struct work_task *ptask) /* I */ { struct batch_request *preq; job *pjob; preq = ptask->wt_parm1; if ((pjob = find_job(preq->rq_ind.rq_delete.rq_objname)) == NULL) { /* job doesn't exist, we're done */ return; } sprintf(log_buffer, "purging job without checking MOM"); log_event( PBSEVENT_JOB, PBS_EVENTCLASS_JOB, pjob->ji_qs.ji_jobid, log_buffer); free_nodes(pjob); if (pjob->ji_qhdr->qu_qs.qu_type == QTYPE_Execution) { set_resc_assigned(pjob, DECR); } job_purge(pjob); } /* END ensure_deleted() */
static void post_modify_req( struct work_task *pwt) { struct batch_request *preq; job *pjob; svr_disconnect(pwt->wt_event); /* close connection to MOM */ preq = pwt->wt_parm1; preq->rq_conn = preq->rq_orgconn; /* restore socket to client */ if ((preq->rq_reply.brp_code) && (preq->rq_reply.brp_code != PBSE_UNKJOBID)) { sprintf(log_buffer, msg_mombadmodify, preq->rq_reply.brp_code); log_event( PBSEVENT_JOB, PBS_EVENTCLASS_JOB, preq->rq_ind.rq_modify.rq_objname, log_buffer); req_reject(preq->rq_reply.brp_code, 0, preq, NULL, NULL); } else { if (preq->rq_reply.brp_code == PBSE_UNKJOBID) { if ((pjob = find_job(preq->rq_ind.rq_modify.rq_objname)) == NULL) { req_reject(preq->rq_reply.brp_code, 0, preq, NULL, NULL); return; } else { if (LOGLEVEL >= 0) { sprintf(log_buffer, "post_modify_req: PBSE_UNKJOBID for job %s in state %s-%s, dest = %s", (pjob->ji_qs.ji_jobid != NULL) ? pjob->ji_qs.ji_jobid : "", PJobState[pjob->ji_qs.ji_state], PJobSubState[pjob->ji_qs.ji_substate], pjob->ji_qs.ji_destin); LOG_EVENT( PBSEVENT_JOB, PBS_EVENTCLASS_JOB, pjob->ji_qs.ji_jobid, log_buffer); } } } reply_ack(preq); } return; } /* END post_modify_req() */
bool Q::cancel(const string& uid) { JobOption job = find_job(uid); if (job.empty()) return false; delete_job(job.get().uid()); return true; }
static void post_rerun(struct work_task *pwt) { job *pjob; struct batch_request *preq; preq = (struct batch_request *)pwt->wt_parm1; if (preq->rq_reply.brp_code != 0) { if ((pjob = find_job(preq->rq_ind.rq_signal.rq_jid)) != NULL) { (void)sprintf(log_buffer, "rerun signal reject by mom: %d", preq->rq_reply.brp_code); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, preq->rq_ind.rq_signal.rq_jid, log_buffer); if ((preq->rq_reply.brp_code == PBSE_UNKJOBID) && (preq->rq_extra == 0)) { pjob->ji_qs.ji_substate = JOB_SUBSTATE_RERUN3; discard_job(pjob, "Force rerun", 1); force_reque(pjob); } } } release_req(pwt); return; }
/* * asfi_func - get the $SFI of an async job */ FUNCTION CODE asfi_func ( struct VALUE *strval, /* in: value containing jobname */ struct CONTXT *context, /* in: TM context */ struct VALUE *numval, /* out: value containing the sfi*/ struct ERRMSG *(*errmsg) /* out: error message */ ) { struct ACB *a; /* find job in acb list */ TEXT *jobname; if ((*strval).type != V_STRING) { *errmsg = &er_notstring; return(FAIL); } jobname = (*strval).uval.strpt; /* jobname */ a = find_job (jobname); if (a == NULL) { *errmsg = &er_nojob; s_copy(jobname, er_nojob.variable); return (FAIL); } inival(numval); /* set some defaults */ (*numval).type = V_INTEGER; (*numval).uval.intval = (*a).sfi; return (SUCCESS); }
int read_machines_file (char* filename) { /* reads machine file and inits machines structure */ char str[1024]; char name[5]; char* pstr, *tok; int read; long long llid; int id; int alloc = 0; int jid, jidx, mid; FILE *fptr = fopen (filename, "r\0"); if (fptr == NULL) return 1; while (!feof(fptr)) { memset(name, 0, sizeof(name)); memset(str, 0, sizeof(str)); if (!(read = fscanf (fptr, "%s %[^\n]s\n", name, str))) break; if (read == 1) return 4; if (name[0] == '\0') break; if (name[0] != 'M' && name[0] != 'm') return 2; if (alloc == total_machines) machines = (struct machine*) realloc(machines, (alloc+=1024) * sizeof(struct machine)); strcpy(machines[total_machines].mname, name); jidx = 0; pstr = (char*)str; tok = (char *)strtok (pstr, " "); while (tok != NULL) { if (tok[0] != 'J' && tok[0] != 'j') return 3; jid = find_job(tok); if (jid == -1) return 1; jobs[jid].count++; machines[total_machines].jobs[jidx] = jid; tok = (char *)strtok ((char*)NULL, " "); jidx++; } machines[total_machines].totjobs = jidx; machines[total_machines].partid = -1; machines[total_machines].partidx = -1; machines[total_machines].partsrno = -1; machines[total_machines].jid = -1; machines[total_machines].rtime = 0; machines[total_machines].workedby = -1; machines[total_machines].workingfor = -1; total_machines++; } fclose (fptr); return 0; }
void delete_job(pid_t pgid) { int jid = find_job(pgid); if (jid >= beg) { free(job[jid]); job[jid] = NULL; } }
void move_to_background(pid_t pgid, int state, char *command, int len) { int jid = find_job(pgid); if (jid < 0) add_job(pgid, state, command, len); else update_job(pgid, state); }
void move_to_foreground(pid_t pgid) { int jid = find_job(pgid); if (jid >= beg) *job[0] = *job[jid]; else printf("%d: No such process\n", (int)pgid); }
JobOption BerkeleyQ::peek(const string& queue_name) { if (!this->active) return JobOption(); DbLock lock = acquire_lock(queue_name, DB_LOCK_READ); vector<string> queue = load_queue_vector(queue_name); release_lock(&lock); return !queue.empty() ? find_job(*queue.begin()) : JobOption(); }
/* Find latest job stopped job or by pgid*/ static job* find_stopped(size_t argc, char** argv) { job* target; if (argc <= 1) { target = find_latest_job(SEARCH_STOPPED); } else { target = find_job(atoi(argv[1])); } return target; }
void update_job(pid_t pgid, int state) { int jid = find_job(pgid); if (beg <= jid && jid < end) { job[jid]->state = state; printf("[%d] %d %s\n", jid, (int)pgid, job[jid]->command); } else { printf("%d: No such process\n", (int)pgid); } }
JobOption BerkeleyQ::update_job_run_at(const string& uid, const long run_at) { if (!this->active) return JobOption(); JobOption job = find_job(uid); if (job.empty()) return JobOption(); Job updated_job = job.get().withRunAt(run_at); save_job_record(updated_job); return JobOption(updated_job); }
void append_job(struct userqueue *q, char *username, char *sha512, char *uuid, char *title, unsigned long created, int pages, int duplex, struct in_addr *src, struct in_addr *dst){ struct jobinfo *j, *p; q->cleaned = clean_queue(q, EXPIRE_TIME); /* don't allocate memory or add job if it exists already even though jobs are uniquely identified by uuid and the cups server to which it was submitted, creation time is a much eaiser first pass comparison */ if ( find_job(q, uuid, created, dst) != NULL ) return; /* Hey, remember that freelist idea? */ j = JOBINFO_ALLOC(); memset(j, 0, sizeof(struct jobinfo)); memcpy(j->uuid, uuid, 32); memcpy(j->sha512, sha512, 128); j->created = created; j->pageinfo = (pages << 1) + duplex; memcpy(&j->src, src, sizeof(struct in_addr)); memcpy(&j->dst, dst, sizeof(struct in_addr)); strncpy(j->username, username, 15); strncpy(j->title, title, 63); if (q->head == NULL){ q->head = j; }else{ p = q->head; /* Progress through the joblist until the next slot is either NULL or occupied by a job of equal or greater creation time */ while (p->next && (p->next->created < created) ){ p = p->next; } /* If the next slot is non-NULL, then move that slot's jobinfo into the next address of this new jobinfo structure and change the p->next to point to our new structure, inserting it before the occupied slot */ if ( p->next ){ j->next = p->next; } p->next = j; } }
JobOption BerkeleyQ::update_job_status(const string& uid, const JobStatus status, const string& status_description) { if (!this->active) return JobOption(); JobOption job = find_job(uid); if (job.empty()) return JobOption(); Job updated_job = job.get().withStatus(status, status_description); save_job_record(updated_job); return JobOption(updated_job); }
/* Continue job with specifed pgid in the background. Control stays with terminal*/ void resume_background_job(pid_t pgid) { job_t* j = find_job(pgid); //ID the stopped job j->bg = true; //If it was in foreground, now in background process_t* p; for (p = j->first_process; p; p = p->next) { if (p->stopped) { //resume all stopped processes in its process group p->stopped = false; p->status = -1; } } continue_job(j); //sends SIGCONT signal to job }
bool job_stop(int id) { Job *job = find_job(id); if (job == NULL || job->stopped) { return false; } job->stopped = true; return true; }
void qmp_job_complete(const char *id, Error **errp) { AioContext *aio_context; Job *job = find_job(id, &aio_context, errp); if (!job) { return; } trace_qmp_job_complete(job); job_complete(job, errp); aio_context_release(aio_context); }
/* Continue job with specifed pgid in the foreground */ void resume_foreground_job(pid_t pgid) { job_t* j = find_job(pgid); //obtain job with specified processs group ID j->bg = false; //if was in background before, it is no longer process_t* p; for (p = j->first_process; p; p = p->next) { if (p->stopped) { //ID stopped processes in specified job and resume them p->stopped = false; p->status = -1; } } tcsetpgrp(shell_terminal, j->pgid); //move the job to the terminal foreground continue_job(j); //send SIGCONT signal wait_on_job(j); //suspend dsh until job exits or stops tcsetpgrp(shell_terminal, shell_pgid); //when foregroung job exits or stops, return control to dsh }
const string Q::post(const string& queue_name, const string& uid, const string& data, const long run_at) { if (!this->active) return ""; if (!uid.empty()) { JobOption existing = find_job(uid); if (!existing.empty()) delete_job(uid); } Job job = Job(uid, data, JSPending, run_at); push_back(queue_name, job); q_log("posted [%s] on [%s] as [%s]", data.c_str(), queue_name.c_str(), job.uid().c_str()); return job.uid(); }
int read_part_jobs_file (char* filename) { /* reads jobs sequence file and inits parts structures */ char str[1024]; char name[NAME_SZ]; char* pstr, *tok; int read, ct; int pid, jid, jidx; FILE *fptr = fopen (filename, "r\0"); if (fptr == NULL) return 1; ct = 0; while (!feof(fptr)) { memset(name, 0, sizeof(name)); memset(str, 0, sizeof(str)); if (!(read = fscanf (fptr, "%s %[^\n]s\n", name, str))) break; if (read == 1) return 4; if (name[0] == '\0') break; if (name[0] != 'P' && name[0] != 'p') return 2; pid = find_part(name); if (pid == -1) return 1; jidx = 0; pstr = (char *) str; tok = (char *)strtok (pstr, " "); while (tok != NULL) { if (tok[0] != 'J' && tok[0] != 'j') return 3; jid = find_job(tok); if (jid == -1) return 2; parts[pid].jobs[jidx] = jid; jidx++; tok = (char *)strtok ((char*)NULL, " "); } parts[pid].jobs[jidx] == -1; parts[pid].totjobs = jidx; ct++; } if (ct != total_parts) return 4; fclose (fptr); return 0; }
bool job_write(int id, char *data, uint32_t len) { Job *job = find_job(id); if (job == NULL || job->stopped) { free(data); return false; } if (!wstream_write(job->in, data, len, true)) { job_stop(job->id); return false; } return true; }
/** * @brief * qmove a job into a reservation * * @parm[in] presv - reservation structure * * @return int * * @retval 0 : Success * @retval -1 : Failure * */ int cnvrt_qmove(resc_resv *presv) { int rc; struct job *pjob; struct work_task wtnew; char *q_job_id, *at; struct batch_request *reqcnvrt; if (gen_task_EndResvWindow(presv)) { (void)resv_purge(presv); return (-1); } pjob = find_job(presv->ri_wattr[(int)RESV_ATR_convert].at_val.at_str); if (pjob != NULL) q_job_id = pjob->ji_qs.ji_jobid; else { (void)resv_purge(presv); return (-1); } if ((reqcnvrt = alloc_br(PBS_BATCH_MoveJob)) == NULL) { (void)resv_purge(presv); return (-1); } reqcnvrt->rq_perm = (presv->ri_brp)->rq_perm; strcpy(reqcnvrt->rq_user, (presv->ri_brp)->rq_user); strcpy(reqcnvrt->rq_host, (presv->ri_brp)->rq_host); snprintf(reqcnvrt->rq_ind.rq_move.rq_jid, sizeof(reqcnvrt->rq_ind.rq_move.rq_jid), "%s", q_job_id); at = strchr(presv->ri_qs.ri_resvID, (int)'.'); if (at) *at = '\0'; snprintf(reqcnvrt->rq_ind.rq_move.rq_destin, sizeof(reqcnvrt->rq_ind.rq_move.rq_destin), "%s", presv->ri_qs.ri_resvID); if (at) *at = '.'; snprintf(pjob->ji_qs.ji_destin, PBS_MAXROUTEDEST, "%s", reqcnvrt->rq_ind.rq_move.rq_destin); rc = cnvrt_local_move(pjob, reqcnvrt); wtnew.wt_parm1 = (void *)presv; cnvrt_delete(&wtnew); if (rc != 0) return (-1); return (0); }
/** * @brief * find_arrayparent - find and return a pointer to the job that is or will be * the parent of the subjob id string * * @param[in] subjobid - sub job id. * * @return parent job */ job * find_arrayparent(char *subjobid) { int i; char idbuf[PBS_MAXSVRJOBID+1]; char *pc; for (i=0; i<PBS_MAXSVRJOBID; i++) { idbuf[i] = *(subjobid + i); if (idbuf[i] == '[') break; } idbuf[++i] = ']'; idbuf[++i] = '\0'; pc = strchr(subjobid, (int)'.'); if (pc) strcat(idbuf, pc); return (find_job(idbuf)); }
JobOption BerkeleyQ::pop_front(const string& queue_name) { if (!active) return JobOption(); JobOption job; DbLock lock = acquire_lock(queue_name, DB_LOCK_WRITE); vector<string> queue = load_queue_vector(queue_name); if (!queue.empty()) { vector<string>::iterator head = queue.begin(); string uid = *head; queue.erase(head); save_queue_vector(queue_name, queue); save_queue_size(queue_name, queue.size()); job = find_job(uid); } release_lock(&lock); return job; }