------------------------------------------------------------
revno: 1543
fixes bug: https://launchpad.net/bugs/568288
author: Scott James Remnant <[email protected]>
committer: Dmitrijs Ledkovs <[email protected]>
branch nick: upstart
timestamp: Thu 2013-10-03 15:43:24 +0100
message:
Do not respawn jobs, that are being stopped and running pre-stop already.
modified:
init/job_process.c
init/tests/test_job_process.c
--
lp:upstart
https://code.launchpad.net/~upstart-devel/upstart/trunk
Your team Upstart Reviewers is subscribed to branch lp:upstart.
To unsubscribe from this branch go to
https://code.launchpad.net/~upstart-devel/upstart/trunk/+edit-subscription
=== modified file 'init/job_process.c'
--- init/job_process.c 2013-10-01 09:42:49 +0000
+++ init/job_process.c 2013-10-03 14:43:24 +0000
@@ -1626,8 +1626,8 @@
* For services that can be respawned, a zero exit status is
* also a failure unless listed.
*/
- if (status || (job->class->respawn && (! job->class->task)))
- {
+ if ((status || (job->class->respawn && (! job->class->task)))
+ && (job->goal == JOB_START)) {
failed = TRUE;
for (size_t i = 0; i < job->class->normalexit_len; i++) {
if (job->class->normalexit[i] == status) {
=== modified file 'init/tests/test_job_process.c'
--- init/tests/test_job_process.c 2013-09-13 04:44:55 +0000
+++ init/tests/test_job_process.c 2013-10-03 14:43:24 +0000
@@ -7771,6 +7771,109 @@
class->respawn = FALSE;
+ /* Check that we don't respawn the job if the running process exits
+ * before the pre-stop process finishes if we were going to stop the
+ * running proecss anyway.
+ */
+ TEST_FEATURE ("with respawn of to be stopped while pre-stop process");
+ class->respawn = TRUE;
+ class->respawn_limit = 5;
+ class->respawn_interval = 10;
+
+ class->process[PROCESS_PRE_STOP] = process_new (class);
+ class->process[PROCESS_PRE_STOP]->command = "echo";
+
+ TEST_ALLOC_FAIL {
+ TEST_ALLOC_SAFE {
+ job = job_new (class, "");
+
+ blocked = blocked_new (job, BLOCKED_EVENT, event);
+ event_block (event);
+ nih_list_add (&job->blocking, &blocked->entry);
+ }
+
+ job->goal = JOB_STOP;
+ job->state = JOB_PRE_STOP;
+ job->pid[PROCESS_MAIN] = 1;
+ job->pid[PROCESS_PRE_STOP] = 2;
+
+ TEST_FREE_TAG (blocked);
+
+ job->blocker = NULL;
+ event->failed = FALSE;
+
+ job->failed = FALSE;
+ job->failed_process = -1;
+ job->exit_status = 0;
+
+ TEST_DIVERT_STDERR (output) {
+ job_process_handler (NULL, 1, NIH_CHILD_EXITED, 0);
+ }
+ rewind (output);
+
+ TEST_EQ (job->goal, JOB_STOP);
+ TEST_EQ (job->state, JOB_PRE_STOP);
+ TEST_EQ (job->pid[PROCESS_MAIN], 0);
+ TEST_EQ (job->pid[PROCESS_PRE_STOP], 2);
+
+ TEST_EQ (event->blockers, 1);
+ TEST_EQ (event->failed, FALSE);
+
+ TEST_EQ_P (job->blocker, NULL);
+
+ TEST_LIST_NOT_EMPTY (&job->blocking);
+ TEST_NOT_FREE (blocked);
+ TEST_EQ_P (blocked->event, event);
+
+ TEST_EQ (job->failed, FALSE);
+ TEST_EQ (job->failed_process, (ProcessType)-1);
+ TEST_EQ (job->exit_status, 0);
+
+ job_process_handler (NULL, 2, NIH_CHILD_EXITED, 0);
+
+ TEST_EQ (job->goal, JOB_STOP);
+ TEST_EQ (job->state, JOB_STOPPING);
+ TEST_EQ (job->pid[PROCESS_MAIN], 0);
+ TEST_EQ (job->pid[PROCESS_PRE_STOP], 0);
+
+ TEST_EQ (job->respawn_count, 0);
+
+ TEST_EQ (event->blockers, 1);
+ TEST_EQ (event->failed, FALSE);
+
+ TEST_LIST_NOT_EMPTY (&job->blocking);
+ TEST_NOT_FREE (blocked);
+ TEST_EQ_P (blocked->event, event);
+ event_unblock (event);
+
+ TEST_NE_P (job->blocker, NULL);
+
+ TEST_LIST_NOT_EMPTY (&job->blocker->blocking);
+
+ blocked = (Blocked *)job->blocker->blocking.next;
+ TEST_ALLOC_SIZE (blocked, sizeof (Blocked));
+ TEST_ALLOC_PARENT (blocked, job->blocker);
+ TEST_EQ (blocked->type, BLOCKED_JOB);
+ TEST_EQ_P (blocked->job, job);
+ nih_free (blocked);
+
+ TEST_LIST_EMPTY (&job->blocker->blocking);
+
+ TEST_EQ (job->failed, FALSE);
+ TEST_EQ (job->failed_process, (ProcessType)-1);
+ TEST_EQ (job->exit_status, 0);
+
+ TEST_FILE_END (output);
+ TEST_FILE_RESET (output);
+
+ nih_free (job);
+ }
+
+ nih_free (class->process[PROCESS_PRE_STOP]);
+ class->process[PROCESS_PRE_STOP] = NULL;
+
+ class->respawn = FALSE;
+
/* Check that a running task that exits while we're waiting for
* the stopping event to finish does not change the state or
* record the exit information since we were stopping anyway and
--
upstart-devel mailing list
[email protected]
Modify settings or unsubscribe at:
https://lists.ubuntu.com/mailman/listinfo/upstart-devel