diff options
-rw-r--r-- | src/pies.h | 5 | ||||
-rw-r--r-- | src/progman.c | 74 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rwxr-xr-x | tests/aux/touchfile (renamed from tests/aux/startup) | 0 | ||||
-rw-r--r-- | tests/shutdown.at | 58 | ||||
-rw-r--r-- | tests/startup.at | 4 | ||||
-rw-r--r-- | tests/testsuite.at | 1 |
7 files changed, 125 insertions, 20 deletions
@@ -139,13 +139,16 @@ enum pies_comp_mode | |||
139 | pies_comp_pass_fd, | 139 | pies_comp_pass_fd, |
140 | 140 | ||
141 | /* Components of this type runs once on program startup. Running other | 141 | /* Components of this type runs once on program startup. Running other |
142 | components is delayed until the last startup component finishes. */ | 142 | components is delayed until the last startup component finishes. */ |
143 | pies_comp_startup, | 143 | pies_comp_startup, |
144 | 144 | ||
145 | /* FIXME: Runs before program termination */ | 145 | /* Components of this type are run right before program termination. |
146 | They have shutdown_timeout seconds to finish their job and terminate | ||
147 | gracefully, othervise they will be terminated forcefully via SIGTERM | ||
148 | (and SIGKILL, for persisting ones). */ | ||
146 | pies_comp_shutdown, | 149 | pies_comp_shutdown, |
147 | 150 | ||
148 | /* | 151 | /* |
149 | ** Init-style components | 152 | ** Init-style components |
150 | */ | 153 | */ |
151 | pies_mark_sysvinit, | 154 | pies_mark_sysvinit, |
diff --git a/src/progman.c b/src/progman.c index a625885..bae82ba 100644 --- a/src/progman.c +++ b/src/progman.c | |||
@@ -284,13 +284,15 @@ register_prog0 (struct component *comp) | |||
284 | 284 | ||
285 | if (comp->mode == pies_comp_inetd) | 285 | if (comp->mode == pies_comp_inetd) |
286 | newp->v.p.status = status_listener; | 286 | newp->v.p.status = status_listener; |
287 | else | 287 | else |
288 | newp->v.p.status = status_stopped; | 288 | newp->v.p.status = status_stopped; |
289 | 289 | ||
290 | if ((comp->flags & CF_DISABLED) || comp->mode == pies_comp_ondemand) | 290 | if ((comp->flags & CF_DISABLED) |
291 | || comp->mode == pies_comp_ondemand | ||
292 | || comp->mode == pies_comp_shutdown) | ||
291 | newp->active = 0; | 293 | newp->active = 0; |
292 | else | 294 | else |
293 | newp->active = 1; | 295 | newp->active = 1; |
294 | 296 | ||
295 | if (comp->mode != pies_comp_exec) | 297 | if (comp->mode != pies_comp_exec) |
296 | comp->redir[RETR_OUT].type = redir_null; | 298 | comp->redir[RETR_OUT].type = redir_null; |
@@ -1792,27 +1794,12 @@ prog_stop (struct prog *prog, int sig) | |||
1792 | if (prog->type == TYPE_COMPONENT && prog->v.p.comp->flags & CF_SIGGROUP) | 1794 | if (prog->type == TYPE_COMPONENT && prog->v.p.comp->flags & CF_SIGGROUP) |
1793 | kill (-prog->pid, sig); | 1795 | kill (-prog->pid, sig); |
1794 | else | 1796 | else |
1795 | kill (prog->pid, sig); | 1797 | kill (prog->pid, sig); |
1796 | } | 1798 | } |
1797 | 1799 | ||
1798 | static int | ||
1799 | mark_for_stopping (struct prog *prog, void *data) | ||
1800 | { | ||
1801 | if (IS_COMPONENT (prog)) | ||
1802 | prog->stop = 1; | ||
1803 | return 0; | ||
1804 | } | ||
1805 | |||
1806 | void | ||
1807 | progman_stop (void) | ||
1808 | { | ||
1809 | progman_foreach (mark_for_stopping, NULL); | ||
1810 | progman_gc (); | ||
1811 | } | ||
1812 | |||
1813 | static void | 1800 | static void |
1814 | print_status (const char *tag, pid_t pid, int status, int expect_term) | 1801 | print_status (const char *tag, pid_t pid, int status, int expect_term) |
1815 | { | 1802 | { |
1816 | int prio; | 1803 | int prio; |
1817 | 1804 | ||
1818 | if (init_process) | 1805 | if (init_process) |
@@ -2579,7 +2566,62 @@ progman_gc (void) | |||
2579 | } | 2566 | } |
2580 | 2567 | ||
2581 | /* FIXME: Report remaining programs */ | 2568 | /* FIXME: Report remaining programs */ |
2582 | 2569 | ||
2583 | } | 2570 | } |
2584 | 2571 | ||
2572 | static int | ||
2573 | start_shutdown (struct prog *prog, void *data) | ||
2574 | { | ||
2575 | if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_shutdown) | ||
2576 | { | ||
2577 | int *p = data; | ||
2578 | if (!*p) | ||
2579 | { | ||
2580 | diagmsg (DIAG_CON, LOG_INFO, "Starting shutdown components"); | ||
2581 | *p = 1; | ||
2582 | } | ||
2583 | prog->active = 1; | ||
2584 | prog_start (prog); | ||
2585 | prog->stop = 1; | ||
2586 | } | ||
2587 | return 0; | ||
2588 | } | ||
2589 | |||
2590 | void | ||
2591 | program_shutdown (void) | ||
2592 | { | ||
2593 | time_t start = time (NULL); | ||
2594 | int sd = 0; | ||
2595 | |||
2596 | /* Activate shutdown components. */ | ||
2597 | progman_foreach (start_shutdown, &sd); | ||
2598 | while (prog_to_stop (proghead)) | ||
2599 | { | ||
2600 | progman_cleanup (1); | ||
2601 | if (time (NULL) - start < shutdown_timeout) | ||
2602 | sleep (1); | ||
2603 | else | ||
2604 | { | ||
2605 | progman_gc (); | ||
2606 | break; | ||
2607 | } | ||
2608 | } | ||
2609 | } | ||
2610 | |||
2611 | static int | ||
2612 | mark_for_stopping (struct prog *prog, void *data) | ||
2613 | { | ||
2614 | if (IS_COMPONENT (prog)) | ||
2615 | prog->stop = 1; | ||
2616 | return 0; | ||
2617 | } | ||
2618 | |||
2619 | void | ||
2620 | progman_stop (void) | ||
2621 | { | ||
2622 | progman_foreach (mark_for_stopping, NULL); | ||
2623 | progman_gc (); | ||
2624 | program_shutdown (); | ||
2625 | } | ||
2626 | |||
2585 | /* EOF */ | 2627 | /* EOF */ |
diff --git a/tests/Makefile.am b/tests/Makefile.am index b2f2719..b404ed4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am | |||
@@ -15,13 +15,13 @@ | |||
15 | # along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. | 15 | # along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | ||
17 | AUXTOOLS = \ | 17 | AUXTOOLS = \ |
18 | aux/respawn\ | 18 | aux/respawn\ |
19 | aux/retcode\ | 19 | aux/retcode\ |
20 | aux/mailer\ | 20 | aux/mailer\ |
21 | aux/startup | 21 | aux/touchfile |
22 | 22 | ||
23 | EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 $(AUXTOOLS) | 23 | EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 $(AUXTOOLS) |
24 | DISTCLEANFILES = atconfig $(check_SCRIPTS) | 24 | DISTCLEANFILES = atconfig $(check_SCRIPTS) |
25 | MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE) | 25 | MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE) |
26 | 26 | ||
27 | ## ------------ ## | 27 | ## ------------ ## |
@@ -50,12 +50,13 @@ TESTSUITE_AT = \ | |||
50 | cyclic.at\ | 50 | cyclic.at\ |
51 | respawn.at\ | 51 | respawn.at\ |
52 | redirect.at\ | 52 | redirect.at\ |
53 | ret-exec.at\ | 53 | ret-exec.at\ |
54 | ret-notify.at\ | 54 | ret-notify.at\ |
55 | startup.at\ | 55 | startup.at\ |
56 | shutdown.at\ | ||
56 | version.at | 57 | version.at |
57 | 58 | ||
58 | TESTSUITE = $(srcdir)/testsuite | 59 | TESTSUITE = $(srcdir)/testsuite |
59 | M4=m4 | 60 | M4=m4 |
60 | 61 | ||
61 | AUTOTEST = $(AUTOM4TE) --language=autotest | 62 | AUTOTEST = $(AUTOM4TE) --language=autotest |
diff --git a/tests/aux/startup b/tests/aux/touchfile index b9d92a3..b9d92a3 100755 --- a/tests/aux/startup +++ b/tests/aux/touchfile | |||
diff --git a/tests/shutdown.at b/tests/shutdown.at new file mode 100644 index 0000000..79bec37 --- /dev/null +++ b/tests/shutdown.at | |||
@@ -0,0 +1,58 @@ | |||
1 | # This file is part of GNU pies testsuite. -*- Autotest -*- | ||
2 | # Copyright (C) 2019 Sergey Poznyakoff | ||
3 | # | ||
4 | # GNU pies is free software; you can redistribute it and/or modify | ||
5 | # it under the terms of the GNU General Public License as published by | ||
6 | # the Free Software Foundation; either version 3, or (at your option) | ||
7 | # any later version. | ||
8 | # | ||
9 | # GNU pies is distributed in the hope that it will be useful, | ||
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | # GNU General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with GNU pies. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AT_SETUP([Shutdown components]) | ||
18 | |||
19 | AT_CHECK([ | ||
20 | PIES_XFAIL_CHECK | ||
21 | PIES_CONTROL_INIT | ||
22 | comp_pid_file=$PWD/comp.pid | ||
23 | |||
24 | cat > pies.conf <<_EOT | ||
25 | component s { | ||
26 | mode shutdown; | ||
27 | command "$auxdir/touchfile $PWD 0 shutdown"; | ||
28 | } | ||
29 | |||
30 | component test { | ||
31 | mode respawn; | ||
32 | command "$auxdir/respawn -append -pid $comp_pid_file"; | ||
33 | } | ||
34 | _EOT | ||
35 | |||
36 | pies --config-file control.conf --config-file pies.conf | ||
37 | |||
38 | n=0 | ||
39 | while : | ||
40 | do | ||
41 | if test -f $comp_pid_file; then | ||
42 | break | ||
43 | fi | ||
44 | sleep 1 | ||
45 | n=$(($n + 1)) | ||
46 | if test $n -gt 10; then | ||
47 | echo >&2 "timed out" | ||
48 | break | ||
49 | fi | ||
50 | done | ||
51 | |||
52 | PIES_STOP | ||
53 | |||
54 | test -f shutdown | ||
55 |