Merge lp:~jamesodhunt/upstart/bug-1227212 into lp:upstart

Proposed by James Hunt
Status: Merged
Merged at revision: 1534
Proposed branch: lp:~jamesodhunt/upstart/bug-1227212
Merge into: lp:upstart
Diff against target: 568 lines (+321/-34)
8 files modified
ChangeLog (+35/-0)
init/event.c (+20/-0)
init/job_process.c (+14/-3)
init/quiesce.c (+176/-23)
init/quiesce.h (+3/-0)
test/test_util_common.c (+24/-5)
test/test_util_common.h (+4/-1)
util/tests/test_initctl.c (+45/-2)
To merge this branch: bzr merge lp:~jamesodhunt/upstart/bug-1227212
Reviewer Review Type Date Requested Status
Dimitri John Ledkov Approve
Review via email: mp+187844@code.launchpad.net

Description of the change

* init/event.c: event_pending_handle_jobs(): Force quiesce when all job
  instances have finished to speed session shutdown.
* init/job_process.c: job_process_jobs_running(): Only consider job
  instances with associated pids to avoid abstract jobs confusing the
  shutdown.
* init/quiesce.c:
  - quiesce(): Optimise session shutdown
    - Skip wait phase if no jobs care about the 'session-end' event
      (LP: #1227212).
    - Stop already running instances if other jobs care about
      'session-end' to allow the already-running jobs to shut down in
       parallel with the newly-started session-end jobs.
  - quiesce_wait_callback():
    - Simplify logic.
    - Improve wait phase checks to detect earliest time to finalise.
  - quiesce_finalise(): Display time to shutdown.
  - quiesce_complete(): New function to force final shutdown phase.
  - quiesce_event_match(): New function to determine if any jobs
    'start on' contains a particular event.
  - quiesce_in_progress(): Determine if shutdown is being handled.
* test/test_util_common.c:
  - _start_upstart(): Call get_upstart_binary() rather than relying on
    UPSTART_BINARY define.
  - start_upstart_common(): Remove '--no-startup-event' as this is now
    needed by a test.
  - get_upstart_binary(): Assert that file exists.
  - file_exists(): New helper function.
* test/test_util_common.h: Typo and prototype.
* util/tests/test_initctl.c: test_quiesce():
  - New test "session shutdown: one long-running job which starts on
    startup".
  - Adjusted expected shutdown times.

-----------------------------

Expected behaviour:

= Common Case =

- If no jobs 'start on session-end', shutdown is "immediate". This is the common case.
  => Shutdown time: 1 second.

= Jobs Specifying 'session-end' =

- If any job specifies 'start on session-end' (no standard jobs do):
  - The shutdown will stop all running job instances.
  - The shutdown will allow session-end jobs to run as long as they complete within 5 seconds.
  => Shutdown time: 5 seconds.

= Jobs Specifying 'session-end' and blocking SIGTERM =

- If no jobs specify 'start on session-end' but some jobs block SIGTERM:
  => Shutdown time: 5 seconds.

- If any job specifies 'start on session-end' and blocks SIGTERM (but
  not other jobs block SIGTERM):
  - The shutdown will wait for up to 5 seconds for the jobs to run.
  - The shutdown will then signal them with SIGTERM and wait for up to a further 5 seconds before sending SIGKILL.
  => Shutdown time: 5+5 = 10 seconds.

- If any job specifies 'start on session-end' and blocks SIGTERM *and* other non-session-end jobs
  running at shutdown also block SIGTERM:
  => Shutdown time: 5+5 = 10 seconds (*).

= Jobs with Long-Running pre-start stanzas =

Job that have long-running pre-start stanzas could also slow down the session shutdown since changing their state will take the duration of the time to execute the pre-start stanza. One of the standard session jobs fell into this category ('logrotate') but has now been fixed.

Note that the SIGTERM case is pathological and should be surmountable using the 'kill signal' stanza (see init(5) and
http://upstart.ubuntu.com/cookbook/#kill-signal).

(*) - Not 15 seconds, since the shutdown will send SIGTERM to all non-session-end jobs such that their kill timer runs in parallel with the session-end jobs wait time.

To post a comment you must log in.
Revision history for this message
Dimitri John Ledkov (xnox) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2013-09-13 04:44:55 +0000
+++ ChangeLog 2013-09-26 16:38:20 +0000
@@ -1,3 +1,38 @@
12013-09-26 James Hunt <james.hunt@ubuntu.com>
2
3 * init/event.c: event_pending_handle_jobs(): Force quiesce when all job
4 instances have finished to speed session shutdown.
5 * init/job_process.c: job_process_jobs_running(): Only consider job
6 instances with associated pids to avoid abstract jobs confusing the
7 shutdown.
8 * init/quiesce.c:
9 - quiesce(): Optimise session shutdown
10 - Skip wait phase if no jobs care about the 'session-end' event
11 (LP: #1227212).
12 - Stop already running instances if other jobs care about
13 'session-end' to allow the already-running jobs to shut down in
14 parallel with the newly-started session-end jobs.
15 - quiesce_wait_callback():
16 - Simplify logic.
17 - Improve wait phase checks to detect earliest time to finalise.
18 - quiesce_finalise(): Display time to shutdown.
19 - quiesce_complete(): New function to force final shutdown phase.
20 - quiesce_event_match(): New function to determine if any jobs
21 'start on' contains a particular event.
22 - quiesce_in_progress(): Determine if shutdown is being handled.
23 * test/test_util_common.c:
24 - _start_upstart(): Call get_upstart_binary() rather than relying on
25 UPSTART_BINARY define.
26 - start_upstart_common(): Remove '--no-startup-event' as this is now
27 needed by a test.
28 - get_upstart_binary(): Assert that file exists.
29 - file_exists(): New helper function.
30 * test/test_util_common.h: Typo and prototype.
31 * util/tests/test_initctl.c: test_quiesce():
32 - New test "session shutdown: one long-running job which starts on
33 startup".
34 - Adjusted expected shutdown times.
35
12013-09-12 Steve Langasek <steve.langasek@ubuntu.com>362013-09-12 Steve Langasek <steve.langasek@ubuntu.com>
237
3 * configure.ac:38 * configure.ac:
439
=== modified file 'init/event.c'
--- init/event.c 2013-06-04 16:51:55 +0000
+++ init/event.c 2013-09-26 16:38:20 +0000
@@ -44,6 +44,7 @@
44#include "blocked.h"44#include "blocked.h"
45#include "control.h"45#include "control.h"
46#include "errors.h"46#include "errors.h"
47#include "quiesce.h"
4748
48#include "com.ubuntu.Upstart.h"49#include "com.ubuntu.Upstart.h"
4950
@@ -299,6 +300,8 @@
299static void300static void
300event_pending_handle_jobs (Event *event)301event_pending_handle_jobs (Event *event)
301{302{
303 int empty = TRUE;
304
302 nih_assert (event != NULL);305 nih_assert (event != NULL);
303306
304 job_class_init ();307 job_class_init ();
@@ -432,6 +435,23 @@
432 event_operator_reset (class->start_on);435 event_operator_reset (class->start_on);
433 }436 }
434 }437 }
438
439 /* Determine if any job instances remain */
440 NIH_HASH_FOREACH_SAFE (job_classes, iter) {
441 JobClass *class = (JobClass *)iter;
442
443 NIH_HASH_FOREACH_SAFE (class->instances, job_iter) {
444 empty = FALSE;
445 break;
446 }
447
448 if (! empty)
449 break;
450 }
451
452 /* If no instances remain, force quiesce to finish */
453 if (empty && quiesce_in_progress ())
454 quiesce_complete ();
435}455}
436456
437457
438458
=== modified file 'init/job_process.c'
--- init/job_process.c 2013-07-01 21:05:15 +0000
+++ init/job_process.c 2013-09-26 16:38:20 +0000
@@ -1259,7 +1259,9 @@
1259/**1259/**
1260 * job_process_jobs_running:1260 * job_process_jobs_running:
1261 *1261 *
1262 * Determine if any jobs are running.1262 * Determine if any jobs are running. Note that simply checking if class
1263 * instances exist is insufficient: since this call is used for shutdown
1264 * abstract jobs must not be able to block the shutdown.
1263 *1265 *
1264 * Returns: TRUE if jobs are still running, else FALSE.1266 * Returns: TRUE if jobs are still running, else FALSE.
1265 **/1267 **/
@@ -1271,8 +1273,17 @@
1271 NIH_HASH_FOREACH (job_classes, iter) {1273 NIH_HASH_FOREACH (job_classes, iter) {
1272 JobClass *class = (JobClass *)iter;1274 JobClass *class = (JobClass *)iter;
12731275
1274 NIH_HASH_FOREACH (class->instances, job_iter)1276 NIH_HASH_FOREACH (class->instances, job_iter) {
1275 return TRUE;1277 Job *job = (Job *)job_iter;
1278 nih_local char *cmd = NULL;
1279 int i;
1280 nih_local char *pids = NULL;
1281
1282 for (i = 0; i < PROCESS_LAST; i++) {
1283 if (job->pid[i])
1284 return TRUE;
1285 }
1286 }
1276 }1287 }
12771288
1278 return FALSE;1289 return FALSE;
12791290
=== modified file 'init/quiesce.c'
--- init/quiesce.c 2013-07-31 09:28:48 +0000
+++ init/quiesce.c 2013-09-26 16:38:20 +0000
@@ -48,9 +48,16 @@
48static QuiescePhase quiesce_phase = QUIESCE_PHASE_NOT_QUIESCED;48static QuiescePhase quiesce_phase = QUIESCE_PHASE_NOT_QUIESCED;
4949
50/**50/**
51 * quiesce_reason:
52 *
53 * Human-readable string denoting what triggered the quiesce.
54 **/
55static char *quiesce_reason = NULL;
56
57/**
51 * max_kill_timeout:58 * max_kill_timeout:
52 *59 *
53 * Maxiumum kill_timout value calculated from all running jobs used to60 * Maxiumum kill_timeout value calculated from all running jobs used to
54 * determine how long to wait before exiting.61 * determine how long to wait before exiting.
55 **/62 **/
56static time_t max_kill_timeout = 0;63static time_t max_kill_timeout = 0;
@@ -62,6 +69,24 @@
62 **/69 **/
63static time_t quiesce_phase_time = 0;70static time_t quiesce_phase_time = 0;
6471
72/**
73 * quiesce_start_time:
74 *
75 * Time quiesce commenced.
76 **/
77static time_t quiesce_start_time = 0;
78
79/**
80 * session_end_jobs:
81 *
82 * TRUE if any job specifies a 'start on' including SESSION_END_EVENT.
83 *
84 **/
85static int session_end_jobs = FALSE;
86
87static int quiesce_event_match (Event *event)
88 __attribute__ ((warn_unused_result));
89
65/* External definitions */90/* External definitions */
66extern int disable_respawn;91extern int disable_respawn;
6792
@@ -76,7 +101,7 @@
76quiesce (QuiesceRequester requester)101quiesce (QuiesceRequester requester)
77{102{
78 nih_local char **env = NULL;103 nih_local char **env = NULL;
79 const char *reason;104 Event *event;
80105
81 job_class_init ();106 job_class_init ();
82107
@@ -98,12 +123,12 @@
98 ? QUIESCE_PHASE_KILL123 ? QUIESCE_PHASE_KILL
99 : QUIESCE_PHASE_WAIT;124 : QUIESCE_PHASE_WAIT;
100125
101 reason = (requester == QUIESCE_REQUESTER_SESSION)126 quiesce_reason = (requester == QUIESCE_REQUESTER_SESSION)
102 ? _("logout") : _("shutdown");127 ? _("logout") : _("shutdown");
103128
104 nih_info (_("Quiescing due to %s request"), reason);129 nih_info (_("Quiescing due to %s request"), quiesce_reason);
105130
106 quiesce_phase_time = time (NULL);131 quiesce_start_time = quiesce_phase_time = time (NULL);
107132
108 /* Stop existing jobs from respawning */133 /* Stop existing jobs from respawning */
109 disable_respawn = TRUE;134 disable_respawn = TRUE;
@@ -116,11 +141,43 @@
116 env = NIH_MUST (nih_str_array_new (NULL));141 env = NIH_MUST (nih_str_array_new (NULL));
117142
118 NIH_MUST (environ_set (&env, NULL, NULL, TRUE,143 NIH_MUST (environ_set (&env, NULL, NULL, TRUE,
119 "TYPE=%s", reason));144 "TYPE=%s", quiesce_reason));
120145
121 NIH_MUST (event_new (NULL, SESSION_END_EVENT, env));146 event = NIH_MUST (event_new (NULL, SESSION_END_EVENT, env));
122147
123 if (requester == QUIESCE_REQUESTER_SYSTEM) {148 /* Check if any jobs care about the session end event. If not,
149 * the wait phase can be avoided entirely resulting in a much
150 * faster shutdown.
151 *
152 * Note that simply checking if running instances exist is not
153 * sufficient since if a job cares about the session end event,
154 * it won't yet have started but needs to be given a chance to
155 * run.
156 */
157 if (quiesce_phase == QUIESCE_PHASE_WAIT) {
158
159 session_end_jobs = quiesce_event_match (event);
160
161 if (session_end_jobs) {
162 /* Some as-yet unscheduled jobs care about the
163 * session end event. They will be started the
164 * next time through the main loop and will be
165 * waited for (hence the quiesce phase is not
166 * changed).
167 *
168 * However, already-running jobs *can* be stopped
169 * at this time since by definition they do not
170 * care about the session end event and may just
171 * as well die now to avoid slowing the shutdown.
172 */
173 job_process_stop_all ();
174 } else {
175 nih_debug ("Skipping wait phase");
176 quiesce_phase = QUIESCE_PHASE_KILL;
177 }
178 }
179
180 if (quiesce_phase == QUIESCE_PHASE_KILL) {
124 /* We'll attempt to wait for this long, but system181 /* We'll attempt to wait for this long, but system
125 * policy may prevent it such that we just get killed182 * policy may prevent it such that we just get killed
126 * and job processes reparented to PID 1.183 * and job processes reparented to PID 1.
@@ -153,32 +210,34 @@
153210
154 nih_assert (timer);211 nih_assert (timer);
155 nih_assert (quiesce_phase_time);212 nih_assert (quiesce_phase_time);
213 nih_assert (quiesce_requester != QUIESCE_REQUESTER_INVALID);
156214
157 now = time (NULL);215 now = time (NULL);
158216
159 nih_assert (quiesce_requester != QUIESCE_REQUESTER_INVALID);217 if (quiesce_phase == QUIESCE_PHASE_KILL) {
160218 nih_assert (max_kill_timeout);
161 if (quiesce_requester == QUIESCE_REQUESTER_SYSTEM) {
162 nih_assert (quiesce_phase == QUIESCE_PHASE_KILL);
163219
164 if ((now - quiesce_phase_time) > max_kill_timeout)220 if ((now - quiesce_phase_time) > max_kill_timeout)
165 goto out;221 goto timed_out;
166222
167 } else if (quiesce_phase == QUIESCE_PHASE_WAIT) {223 } else if (quiesce_phase == QUIESCE_PHASE_WAIT) {
168224 int timed_out = 0;
169 if ((now - quiesce_phase_time) > QUIESCE_DEFAULT_JOB_RUNTIME) {225
226 timed_out = ((now - quiesce_phase_time) >= QUIESCE_DEFAULT_JOB_RUNTIME);
227
228 if (timed_out
229 || (session_end_jobs && ! job_process_jobs_running ())
230 || ! job_process_jobs_running ()) {
231
170 quiesce_phase = QUIESCE_PHASE_KILL;232 quiesce_phase = QUIESCE_PHASE_KILL;
171233
172 /* reset for new phase */234 /* reset for new phase */
173 quiesce_phase_time = time (NULL);235 quiesce_phase_time = time (NULL);
174236
175 max_kill_timeout = job_class_max_kill_timeout ();237 max_kill_timeout = job_class_max_kill_timeout ();
238
176 job_process_stop_all ();239 job_process_stop_all ();
177 }240 }
178 } else if (quiesce_phase == QUIESCE_PHASE_KILL) {
179
180 if ((now - quiesce_phase_time) > max_kill_timeout)
181 goto out;
182 } else {241 } else {
183 nih_assert_not_reached ();242 nih_assert_not_reached ();
184 }243 }
@@ -188,9 +247,10 @@
188247
189 return;248 return;
190249
250timed_out:
251 quiesce_show_slow_jobs ();
252
191out:253out:
192 quiesce_show_slow_jobs ();
193
194 /* Note that we might skip the kill phase for the session254 /* Note that we might skip the kill phase for the session
195 * requestor if no jobs are actually running at this point.255 * requestor if no jobs are actually running at this point.
196 */256 */
@@ -237,7 +297,100 @@
237void297void
238quiesce_finalise (void)298quiesce_finalise (void)
239{299{
300 static int finalising = FALSE;
301 time_t diff;
302
303 nih_assert (quiesce_start_time);
240 nih_assert (quiesce_phase == QUIESCE_PHASE_CLEANUP);304 nih_assert (quiesce_phase == QUIESCE_PHASE_CLEANUP);
241305
306 if (finalising)
307 return;
308
309 finalising = TRUE;
310
311 diff = time (NULL) - quiesce_start_time;
312
313 nih_info (_("Quiesce %s sequence took %s%d second%s"),
314 quiesce_reason,
315 ! (int)diff ? "<" : "",
316 (int)diff ? (int)diff : 1,
317 diff <= 1 ? "" : "s");
318
242 nih_main_loop_exit (0);319 nih_main_loop_exit (0);
320
321}
322
323/**
324 * quiesce_complete:
325 *
326 * Force quiesce phase to finish.
327 **/
328void
329quiesce_complete (void)
330{
331 quiesce_phase = QUIESCE_PHASE_CLEANUP;
332
333 quiesce_finalise ();
334}
335
336/**
337 * quiesce_event_match:
338 * @event: event.
339 *
340 * Identify if any jobs _may_ start when the session ends.
341 *
342 * A simple heuristic is used such that there is no guarantee that the
343 * jobs entire start condition will be satisfied at session-end.
344 *
345 * Returns: TRUE if any class specifies @event in its start
346 * condition, else FALSE.
347 **/
348static int
349quiesce_event_match (Event *event)
350{
351 nih_assert (event);
352
353 job_class_init ();
354
355 NIH_HASH_FOREACH (job_classes, iter) {
356 JobClass *class = (JobClass *)iter;
357
358 if (! class->start_on)
359 continue;
360
361 /* Note that only the jobs start on condition is
362 * relevant.
363 */
364 NIH_TREE_FOREACH_POST (&class->start_on->node, iter) {
365 EventOperator *oper = (EventOperator *)iter;
366
367 switch (oper->type) {
368 case EVENT_OR:
369 case EVENT_AND:
370 break;
371 case EVENT_MATCH:
372 /* Job may attempt to start as the session ends */
373 if (event_operator_match (oper, event, NULL))
374 return TRUE;
375 break;
376 default:
377 nih_assert_not_reached ();
378 }
379 }
380 }
381
382 return FALSE;
383}
384
385/**
386 * quiesce_in_progress:
387 *
388 * Determine if shutdown is in progress.
389 *
390 * Returns: TRUE if quiesce is in progress, else FALSE.
391 **/
392int
393quiesce_in_progress (void)
394{
395 return quiesce_phase != QUIESCE_PHASE_NOT_QUIESCED;
243}396}
244397
=== modified file 'init/quiesce.h'
--- init/quiesce.h 2013-02-08 16:15:23 +0000
+++ init/quiesce.h 2013-09-26 16:38:20 +0000
@@ -70,6 +70,9 @@
70void quiesce_wait_callback (void *data, NihTimer *timer);70void quiesce_wait_callback (void *data, NihTimer *timer);
71void quiesce_show_slow_jobs (void);71void quiesce_show_slow_jobs (void);
72void quiesce_finalise (void);72void quiesce_finalise (void);
73void quiesce_complete (void);
74int quiesce_in_progress (void)
75 __attribute__ ((warn_unused_result));
7376
74NIH_END_EXTERN77NIH_END_EXTERN
7578
7679
=== modified file 'test/test_util_common.c'
--- test/test_util_common.c 2013-07-17 14:18:42 +0000
+++ test/test_util_common.c 2013-09-26 16:38:20 +0000
@@ -384,7 +384,7 @@
384 argv = NIH_MUST (nih_str_array_new (NULL));384 argv = NIH_MUST (nih_str_array_new (NULL));
385385
386 NIH_MUST (nih_str_array_add (&argv, NULL, NULL,386 NIH_MUST (nih_str_array_add (&argv, NULL, NULL,
387 UPSTART_BINARY));387 get_upstart_binary ()));
388388
389 if (args)389 if (args)
390 NIH_MUST (nih_str_array_append (&argv, NULL, NULL, args));390 NIH_MUST (nih_str_array_append (&argv, NULL, NULL, args));
@@ -447,9 +447,6 @@
447 }447 }
448448
449 NIH_MUST (nih_str_array_add (&args, NULL, NULL,449 NIH_MUST (nih_str_array_add (&args, NULL, NULL,
450 "--no-startup-event"));
451
452 NIH_MUST (nih_str_array_add (&args, NULL, NULL,
453 "--no-sessions"));450 "--no-sessions"));
454451
455 NIH_MUST (nih_str_array_add (&args, NULL, NULL,452 NIH_MUST (nih_str_array_add (&args, NULL, NULL,
@@ -561,7 +558,11 @@
561const char *558const char *
562get_upstart_binary (void)559get_upstart_binary (void)
563{560{
564 return UPSTART_BINARY;561 static const char *upstart_binary = UPSTART_BINARY;
562
563 TEST_TRUE (file_exists (upstart_binary));
564
565 return upstart_binary;
565}566}
566567
567const char *568const char *
@@ -740,3 +741,21 @@
740741
741 return new;742 return new;
742}743}
744
745/**
746 * file_exists:
747 * @path: file to check.
748 *
749 * Determine if specified file exists.
750 *
751 * Returns: TRUE if @path exists, else FALSE.
752 **/
753int
754file_exists (const char *path)
755{
756 struct stat st;
757
758 nih_assert (path);
759
760 return ! stat (path, &st);
761}
743762
=== modified file 'test/test_util_common.h'
--- test/test_util_common.h 2013-07-17 14:18:42 +0000
+++ test/test_util_common.h 2013-09-26 16:38:20 +0000
@@ -10,7 +10,7 @@
10#define BUFFER_SIZE 102410#define BUFFER_SIZE 1024
1111
12/**12/**
13 * TEST_QUIESCE_WAIT_PHASE:13 * TEST_EXIT_TIME:
14 *14 *
15 * Maximum time we expect upstart to wait in the QUIESCE_PHASE_WAIT15 * Maximum time we expect upstart to wait in the QUIESCE_PHASE_WAIT
16 * phase.16 * phase.
@@ -733,4 +733,7 @@
733 const char *from, const char *to)733 const char *from, const char *to)
734 __attribute__ ((warn_unused_result));734 __attribute__ ((warn_unused_result));
735735
736int file_exists (const char *path)
737 __attribute__ ((warn_unused_result));
738
736#endif /* TEST_UTIL_COMMON_H */739#endif /* TEST_UTIL_COMMON_H */
737740
=== modified file 'util/tests/test_initctl.c'
--- util/tests/test_initctl.c 2013-09-05 16:19:06 +0000
+++ util/tests/test_initctl.c 2013-09-26 16:38:20 +0000
@@ -11590,6 +11590,49 @@
11590 DELETE_FILE (confdir, "long-running.conf");11590 DELETE_FILE (confdir, "long-running.conf");
1159111591
11592 /*******************************************************************/11592 /*******************************************************************/
11593 TEST_FEATURE ("session shutdown: one long-running job which starts on startup");
11594
11595 CREATE_FILE (confdir, "startup.conf",
11596 "start on startup\n"
11597 "exec sleep 999");
11598
11599 start_upstart_common (&upstart_pid, TRUE, confdir, logdir, NULL);
11600
11601 upstart = upstart_open (NULL);
11602 TEST_NE_P (upstart, NULL);
11603
11604 /* Should be running */
11605 assert0 (kill (upstart_pid, 0));
11606
11607 job_pid = job_to_pid ("startup");
11608 TEST_NE (job_pid, -1);
11609
11610 /* Force reset */
11611 test_user_mode = FALSE;
11612
11613 /* Trigger session shutdown */
11614 assert0 (upstart_end_session_sync (NULL, upstart));
11615
11616 /* Session Init should end very quickly since there will be no
11617 * wait phase.
11618 */
11619 TEST_EQ (timed_waitpid (upstart_pid, TEST_QUIESCE_KILL_PHASE), upstart_pid);
11620
11621 /* Should not now be running */
11622 TEST_EQ (kill (upstart_pid, 0), -1);
11623 TEST_EQ (errno, ESRCH);
11624
11625 session_file = NIH_MUST (nih_sprintf (NULL, "%s/upstart/sessions/%d.session",
11626 sessiondir, (int)upstart_pid));
11627 unlink (session_file);
11628
11629 /* pid should no longer exist */
11630 TEST_EQ (kill (job_pid, SIGKILL), -1);
11631 TEST_EQ (errno, ESRCH);
11632
11633 DELETE_FILE (confdir, "startup.conf");
11634
11635 /*******************************************************************/
11593 TEST_FEATURE ("session shutdown: one long-running job which ignores SIGTERM");11636 TEST_FEATURE ("session shutdown: one long-running job which ignores SIGTERM");
1159411637
11595 CREATE_FILE (confdir, "long-running-term.conf",11638 CREATE_FILE (confdir, "long-running-term.conf",
@@ -11668,7 +11711,7 @@
11668 /* Trigger session shutdown */11711 /* Trigger session shutdown */
11669 assert0 (upstart_end_session_sync (NULL, upstart));11712 assert0 (upstart_end_session_sync (NULL, upstart));
1167011713
11671 TEST_EQ (timed_waitpid (upstart_pid, TEST_QUIESCE_KILL_PHASE), upstart_pid);11714 TEST_EQ (timed_waitpid (upstart_pid, TEST_QUIESCE_TOTAL_WAIT_TIME), upstart_pid);
1167211715
11673 /* Should not now be running */11716 /* Should not now be running */
11674 TEST_EQ (kill (upstart_pid, 0), -1);11717 TEST_EQ (kill (upstart_pid, 0), -1);
@@ -11731,7 +11774,7 @@
11731 /* Trigger session shutdown */11774 /* Trigger session shutdown */
11732 assert0 (upstart_end_session_sync (NULL, upstart));11775 assert0 (upstart_end_session_sync (NULL, upstart));
1173311776
11734 TEST_EQ (timed_waitpid (upstart_pid, TEST_QUIESCE_KILL_PHASE), upstart_pid);11777 TEST_EQ (timed_waitpid (upstart_pid, TEST_QUIESCE_TOTAL_WAIT_TIME), upstart_pid);
1173511778
11736 /* Should not now be running */11779 /* Should not now be running */
11737 TEST_EQ (kill (upstart_pid, 0), -1);11780 TEST_EQ (kill (upstart_pid, 0), -1);

Subscribers

People subscribed via source and target branches