version 1.95, 2007/10/09 09:35:43 |
version 1.96, 2007/10/09 09:39:21 |
|
|
|
|
/* |
/* |
* When JobStart attempts to run a job but isn't allowed to, |
* When JobStart attempts to run a job but isn't allowed to, |
* the job is placed on the stoppedJobs queue to be run |
* the job is placed on the queuedJobs queue to be run |
* when the next job finishes. |
* when the next job finishes. |
*/ |
*/ |
static LIST stoppedJobs; /* Lst of Job structures describing |
static LIST stoppedJobs; |
* jobs that were stopped due to concurrency |
static LIST queuedJobs; |
* limits or migration home */ |
|
|
|
|
|
#if defined(USE_PGRP) && defined(SYSV) |
#if defined(USE_PGRP) && defined(SYSV) |
|
|
static FILE *new_command_file(void); |
static FILE *new_command_file(void); |
static void setup_signal(int); |
static void setup_signal(int); |
static void setup_all_signals(void); |
static void setup_all_signals(void); |
|
static void start_queued_job(Job *); |
|
|
static volatile sig_atomic_t got_signal; |
static volatile sig_atomic_t got_signal; |
|
|
|
|
argv[argc] = NULL; |
argv[argc] = NULL; |
} |
} |
|
|
|
static void |
|
start_queued_job(Job *job) |
|
{ |
|
/* |
|
* Set up the control arguments to the shell. This is based on |
|
* the flags set earlier for this job. If the JOB_IGNERR flag |
|
* is clear, the 'exit' flag of the commandShell is used to |
|
* cause it to exit upon receiving an error. If the JOB_SILENT |
|
* flag is clear, the 'echo' flag of the commandShell is used |
|
* to get it to start echoing as soon as it starts processing |
|
* commands. |
|
*/ |
|
char *argv[4]; |
|
|
|
JobMakeArgv(job, argv); |
|
|
|
if (DEBUG(JOB)) { |
|
(void)fprintf(stdout, "Restarting %s...", |
|
job->node->name); |
|
(void)fflush(stdout); |
|
} |
|
if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL)) { |
|
/* |
|
* Can't be exported and not allowed to run locally -- |
|
* put it back on the hold queue and mark the table |
|
* full |
|
*/ |
|
debug_printf("holding\n"); |
|
Lst_AtFront(&stoppedJobs, job); |
|
jobFull = true; |
|
debug_printf("Job queue is full.\n"); |
|
return; |
|
} else { |
|
/* |
|
* Job may be run locally. |
|
*/ |
|
debug_printf("running locally\n"); |
|
} |
|
JobExec(job, argv); |
|
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* JobRestart -- |
* JobRestart -- |
|
|
JobRestart(Job *job) |
JobRestart(Job *job) |
{ |
{ |
if (job->flags & JOB_RESTART) { |
if (job->flags & JOB_RESTART) { |
/* |
start_queued_job(job); |
* Set up the control arguments to the shell. This is based on |
|
* the flags set earlier for this job. If the JOB_IGNERR flag |
|
* is clear, the 'exit' flag of the commandShell is used to |
|
* cause it to exit upon receiving an error. If the JOB_SILENT |
|
* flag is clear, the 'echo' flag of the commandShell is used |
|
* to get it to start echoing as soon as it starts processing |
|
* commands. |
|
*/ |
|
char *argv[4]; |
|
|
|
JobMakeArgv(job, argv); |
|
|
|
if (DEBUG(JOB)) { |
|
(void)fprintf(stdout, "Restarting %s...", |
|
job->node->name); |
|
(void)fflush(stdout); |
|
} |
|
if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL)) { |
|
/* |
|
* Can't be exported and not allowed to run locally -- |
|
* put it back on the hold queue and mark the table |
|
* full |
|
*/ |
|
debug_printf("holding\n"); |
|
Lst_AtFront(&stoppedJobs, job); |
|
jobFull = true; |
|
debug_printf("Job queue is full.\n"); |
|
return; |
|
} else { |
|
/* |
|
* Job may be run locally. |
|
*/ |
|
debug_printf("running locally\n"); |
|
} |
|
JobExec(job, argv); |
|
} else { |
} else { |
/* |
/* |
* The job has stopped and needs to be restarted. Why it |
* The job has stopped and needs to be restarted. Why it |
|
|
(void)fflush(job->cmdFILE); |
(void)fflush(job->cmdFILE); |
} |
} |
|
|
/* |
|
* Set up the control arguments to the shell. This is based on the flags |
|
* set earlier for this job. |
|
*/ |
|
JobMakeArgv(job, argv); |
|
|
|
/* Create the pipe by which we'll get the shell's output. |
/* Create the pipe by which we'll get the shell's output. |
*/ |
*/ |
if (pipe(fd) == -1) |
if (pipe(fd) == -1) |
|
|
(void)fcntl(job->inPipe, F_SETFD, FD_CLOEXEC); |
(void)fcntl(job->inPipe, F_SETFD, FD_CLOEXEC); |
(void)fcntl(job->outPipe, F_SETFD, FD_CLOEXEC); |
(void)fcntl(job->outPipe, F_SETFD, FD_CLOEXEC); |
|
|
|
/* |
|
* Set up the control arguments to the shell. This is based on the flags |
|
* set earlier for this job. |
|
*/ |
|
JobMakeArgv(job, argv); |
|
|
if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL) && |
if (nJobs >= maxJobs && !(job->flags & JOB_SPECIAL) && |
maxJobs != 0) { |
maxJobs != 0) { |
/* |
/* |
|
|
{ |
{ |
Static_Lst_Init(&runningJobs); |
Static_Lst_Init(&runningJobs); |
Static_Lst_Init(&stoppedJobs); |
Static_Lst_Init(&stoppedJobs); |
|
Static_Lst_Init(&queuedJobs); |
maxJobs = maxproc; |
maxJobs = maxproc; |
nJobs = 0; |
nJobs = 0; |
jobFull = false; |
jobFull = false; |