void scan_for_terminated(void) { static char id[] = "scan_for_terminated"; int exiteval = 0; pid_t pid; job *pjob; task *ptask = NULL; int statloc; unsigned int momport = 0; int tcount; if (LOGLEVEL >= 7) { log_record( PBSEVENT_JOB, PBS_EVENTCLASS_JOB, id, "entered"); } /* update the latest intelligence about the running jobs; */ /* must be done before we reap the zombies, else we lose the info */ termin_child = 0; if (mom_get_sample() == PBSE_NONE) { pjob = (job *)GET_PRIOR(svr_alljobs); while (pjob != NULL) { mom_set_use(pjob); pjob = (job *)GET_PRIOR(pjob->ji_alljobs); } } /* Now figure out which task(s) have terminated (are zombies) */ /* NOTE: does a job's tasks include its epilog? */ while ((pid = waitpid(-1, &statloc, WNOHANG)) > 0) { pjob = (job *)GET_PRIOR(svr_alljobs); while (pjob != NULL) { /* * see if process was a child doing a special * function for MOM */ if (LOGLEVEL >= 7) { snprintf(log_buffer, 1024, "checking job w/subtask pid=%d (child pid=%d)", pjob->ji_momsubt, pid); LOG_EVENT( PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, pjob->ji_qs.ji_jobid, log_buffer); } if (pid == pjob->ji_momsubt) { if (LOGLEVEL >= 7) { snprintf(log_buffer, 1024, "found match with job subtask for pid=%d", pid); LOG_EVENT( PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, pjob->ji_qs.ji_jobid, log_buffer); } break; } /* look for task */ ptask = (task *)GET_NEXT(pjob->ji_tasks); /* locate task with associated process id */ tcount = 0; while (ptask != NULL) { if (ptask->ti_qs.ti_sid == pid) { if (LOGLEVEL >= 7) { snprintf(log_buffer, 1024, "found match with job task %d for pid=%d", tcount, pid); LOG_EVENT( PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, pjob->ji_qs.ji_jobid, log_buffer); } break; } ptask = (task *)GET_NEXT(ptask->ti_jobtask); tcount++; } /* END while (ptask) */ if (ptask != NULL) { /* pid match located - break out of job loop */ break; } pjob = (job *)GET_PRIOR(pjob->ji_alljobs); } /* END while (pjob != NULL) */ if (pjob == NULL) { if (LOGLEVEL >= 1) { sprintf(log_buffer, "pid %d not tracked, exitcode=%d", pid, statloc); log_record( PBSEVENT_JOB, PBS_EVENTCLASS_JOB, id, log_buffer); } continue; } /* END if (pjob == NULL) */ if (WIFEXITED(statloc)) exiteval = WEXITSTATUS(statloc); else if (WIFSIGNALED(statloc)) exiteval = WTERMSIG(statloc) + 0x100; else exiteval = 1; if (pid == pjob->ji_momsubt) { /* PID matches job mom subtask */ /* NOTE: both ji_momsubt and ji_mompost normally set in routine preobit_reply() after epilog child is successfully forked */ if (pjob->ji_mompost != NULL) { if (pjob->ji_mompost(pjob, exiteval) == 0) { /* success */ pjob->ji_mompost = NULL; } } /* END if (pjob->ji_mompost != NULL) */ else { log_record( PBSEVENT_JOB, PBS_EVENTCLASS_JOB, pjob->ji_qs.ji_jobid, "job has no postprocessing routine registered"); } /* clear mom sub-task */ pjob->ji_momsubt = 0; if(multi_mom) { momport = pbs_rm_port; } job_save(pjob, SAVEJOB_QUICK, momport); continue; } /* END if (pid == pjob->ji_momsubt) */ /* what happens if mom PID is reaped before subtask? */ if (LOGLEVEL >= 2) { sprintf(log_buffer, "pid %d harvested for job %s, task %d, exitcode=%d", pid, pjob->ji_qs.ji_jobid, ptask->ti_qs.ti_task, exiteval); log_record( PBSEVENT_JOB, PBS_EVENTCLASS_JOB, id, log_buffer); } /* where is job purged? How do we keep job from progressing in state until the obit is sent? */ kill_task(ptask, SIGKILL, 0); ptask->ti_qs.ti_exitstat = exiteval; ptask->ti_qs.ti_status = TI_STATE_EXITED; task_save(ptask); sprintf(log_buffer, "%s: job %s task %d terminated, sid=%d", id, pjob->ji_qs.ji_jobid, ptask->ti_qs.ti_task, ptask->ti_qs.ti_sid); LOG_EVENT( PBSEVENT_DEBUG, PBS_EVENTCLASS_JOB, pjob->ji_qs.ji_jobid, log_buffer); exiting_tasks = 1; } /* END while ((pid = waitpid(-1,&statloc,WNOHANG)) > 0) */ return; } /* END scan_for_terminated() */
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; }