diff options
-rw-r--r-- | src/comp.c | 65 | ||||
-rw-r--r-- | src/pies.c | 3 | ||||
-rw-r--r-- | src/pies.h | 8 | ||||
-rw-r--r-- | src/progman.c | 47 | ||||
-rw-r--r-- | src/socket.c | 4 | ||||
-rw-r--r-- | tests/Makefile.am | 9 | ||||
-rw-r--r-- | tests/atlocal.in | 2 | ||||
-rwxr-xr-x | tests/aux/mailer (renamed from tests/mailer) | 0 | ||||
-rwxr-xr-x | tests/aux/respawn (renamed from tests/respawn) | 0 | ||||
-rwxr-xr-x | tests/aux/retcode (renamed from tests/retcode) | 0 | ||||
-rwxr-xr-x | tests/aux/startup | 7 | ||||
-rw-r--r-- | tests/redirect.at | 2 | ||||
-rw-r--r-- | tests/respawn.at | 2 | ||||
-rw-r--r-- | tests/ret-exec.at | 4 | ||||
-rw-r--r-- | tests/ret-notify.at | 6 | ||||
-rw-r--r-- | tests/startup.at | 84 | ||||
-rw-r--r-- | tests/testsuite.at | 1 |
17 files changed, 213 insertions, 31 deletions
@@ -26,2 +26,7 @@ struct complist +/* 0 on the first load, and 1 on all subsequent reloads. Tells the + component_config_commit whether we're starting from scratch or just + updating an already loaded configuration */ +static int loaded; + static struct complist comp_list[2]; @@ -34,3 +39,3 @@ static pies_depmap_t depmap; -static int +static inline int next_index (void) @@ -40,3 +45,3 @@ next_index (void) -static int +static inline int prev_index (void) @@ -87,2 +92,18 @@ component_append (struct component *comp) void +comp_array_remove (size_t i) +{ + struct component *comp = comp_array[i]; + + depmap_remove (depmap, i); + while (i < comp_count -1) + { + comp_array[i] = comp_array[i+1]; + comp_array[i]->arridx = i; + i++; + } + component_free (comp); + comp_count--; +} + +void component_unlink (struct component *comp) @@ -203,4 +224,9 @@ component_ref_decr (struct component *comp) if (--comp->ref_count == 0) + { + if (component_is_active (comp)) + comp_array_remove (comp->arridx); + else component_free (comp); } +} @@ -427,13 +453,2 @@ report_cyclic_dependency (pies_depmap_t dp, size_t idx) void -comp_array_remove (size_t i) -{ - struct component *comp = comp_array[i]; - if (i < comp_count - 1) - memmove (&comp_array[i], &comp_array[i+1], - (comp_count - i - 1) * sizeof comp_array[0]); - component_free (comp); - comp_count--; -} - -void component_build_depmap (void) @@ -462,3 +477,2 @@ component_build_depmap (void) comp_array_remove (i); - depmap_remove (depmap, i); continue; @@ -499,6 +513,3 @@ component_build_depmap (void) if (comp_array[i]->flags & CF_REMOVE) - { comp_array_remove (i); - depmap_remove (depmap, i); - } else @@ -530,4 +541,13 @@ component_config_commit (void) - /* Rearrange components, registering prog entries for the new ones */ - for (comp = list->head, i = 0; comp; comp = comp->next, i++) + /* Rearrange components, registering entries for the new ones */ + for (comp = list->head, i = 0; comp; ) + { + struct component *next = comp->next; + if (loaded && comp->mode == pies_comp_startup) + { + /* Ignore startup components */ + component_unlink (comp); + component_free (comp); + } + else { @@ -545,3 +565,8 @@ component_config_commit (void) comp->arridx = i; + i++; + } + comp = next; } + /* Adjust comp_count */ + comp_count = i; @@ -562,2 +587,4 @@ component_config_commit (void) register_prog (comp); + + loaded = 1; } @@ -822,2 +822,4 @@ static struct tokendef modetab[] = { {"pass", pies_comp_pass_fd}, + {"startup", pies_comp_startup}, + {"shutdown", pies_comp_shutdown}, {"boot", pies_comp_boot}, @@ -2230,2 +2232,3 @@ main (int argc, char **argv) progman_create_sockets (); + program_init_startup (); progman_start (); @@ -140,2 +140,9 @@ enum pies_comp_mode + /* Components of this type runs once on program startup. Running other + components is delayed until the last startup component finishes. */ + pies_comp_startup, + + /* FIXME: Runs before program termination */ + pies_comp_shutdown, + /* @@ -336,2 +343,3 @@ int pies_reread_config (void); void register_prog (struct component *comp); +void program_init_startup (void); int progman_waiting_p (void); diff --git a/src/progman.c b/src/progman.c index 1b09cd5..5bc4eb3 100644 --- a/src/progman.c +++ b/src/progman.c @@ -319,2 +319,15 @@ register_command (char *tag, char *command, pid_t pid) +static inline int +progman_startup_phase (void) +{ + struct prog *prog; + + for (prog = proghead; prog; prog = prog->next) + { + if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup) + return 1; + } + return 0; +} + int @@ -326,3 +339,5 @@ progman_waiting_p (void) { - if (IS_COMPONENT (prog) && prog->wait && prog->pid > 0) + if (IS_COMPONENT (prog) + && prog->pid > 0 + && (prog->wait || prog->v.p.comp->mode == pies_comp_startup)) { @@ -1528,2 +1543,21 @@ progman_recompute_alarm (void) void +program_init_startup (void) +{ + struct prog *prog; + + for (prog = proghead; prog; prog = prog->next) + if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup) + { + debug (1, ("running startup components")); + break; + } + + for (; prog; prog = prog->next) + if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup) + { + prog_start (prog); + } +} + +void progman_start (void) @@ -1533,3 +1567,4 @@ progman_start (void) if (progman_waiting_p ()) - /* Noting to do if there are processes left in the previous runlevel */ + /* Noting to do if there are processes left in the previous runlevel + (in sysv-init mode) or startup components running. */ return; @@ -2323,2 +2358,10 @@ progman_cleanup (int expect_term) } + else if (prog->v.p.comp->mode == pies_comp_startup) + { + debug (1, (_("removing startup component %s, pid=%lu"), + prog_tag (prog), (unsigned long)pid)); + destroy_prog (&prog); + if (!progman_startup_phase ()) + pies_schedule_children (PIES_CHLD_WAKEUP); + } else diff --git a/src/socket.c b/src/socket.c index aa01543..40c7aa7 100644 --- a/src/socket.c +++ b/src/socket.c @@ -26,2 +26,4 @@ switch_eids (uid_t *puid, gid_t *pgid, mode_t *pumask) + if ((*puid && *puid != ouid) || (*pgid && *pgid != ogid)) + { if (setegid (*pgid)) @@ -32,2 +34,3 @@ switch_eids (uid_t *puid, gid_t *pgid, mode_t *pumask) (unsigned long) *puid, strerror (errno)); + } *puid = ouid; @@ -639,2 +642 @@ pies_pause (void) } - diff --git a/tests/Makefile.am b/tests/Makefile.am index 447104b..b2f2719 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,3 +16,9 @@ -EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 respawn retcode mailer +AUXTOOLS = \ + aux/respawn\ + aux/retcode\ + aux/mailer\ + aux/startup + +EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 $(AUXTOOLS) DISTCLEANFILES = atconfig $(check_SCRIPTS) @@ -48,2 +54,3 @@ TESTSUITE_AT = \ ret-notify.at\ + startup.at\ version.at diff --git a/tests/atlocal.in b/tests/atlocal.in index 9069bbd..1992b80 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -6,3 +6,3 @@ PATH=@abs_builddir@:@abs_top_builddir@/src:$srcdir:$PATH XFAILFILE=$abs_builddir/.badversion - +auxdir="$abs_srcdir/aux" trimws() { diff --git a/tests/mailer b/tests/aux/mailer index f832ff5..f832ff5 100755 --- a/tests/mailer +++ b/tests/aux/mailer diff --git a/tests/respawn b/tests/aux/respawn index 11d59f6..11d59f6 100755 --- a/tests/respawn +++ b/tests/aux/respawn diff --git a/tests/retcode b/tests/aux/retcode index b827ba9..b827ba9 100755 --- a/tests/retcode +++ b/tests/aux/retcode diff --git a/tests/aux/startup b/tests/aux/startup new file mode 100755 index 0000000..b9d92a3 --- /dev/null +++ b/tests/aux/startup @@ -0,0 +1,7 @@ +#!/bin/sh +dir=${1:?} +time=${2:?} +tag=${3:?} + +touch $dir/$tag +sleep $time diff --git a/tests/redirect.at b/tests/redirect.at index 9e53ba2..3a8cca7 100644 --- a/tests/redirect.at +++ b/tests/redirect.at @@ -26,3 +26,3 @@ component test { mode respawn; - command "$abs_srcdir/respawn -tag respawn -append -pid $comp_pid_file"; + command "$auxdir/respawn -tag respawn -append -pid $comp_pid_file"; stdout file "$outfile"; diff --git a/tests/respawn.at b/tests/respawn.at index 8d72c40..4a8e3a7 100644 --- a/tests/respawn.at +++ b/tests/respawn.at @@ -25,3 +25,3 @@ component test { mode respawn; - command "$abs_srcdir/respawn -append -pid $comp_pid_file"; + command "$auxdir/respawn -append -pid $comp_pid_file"; } diff --git a/tests/ret-exec.at b/tests/ret-exec.at index bf2c1a4..0b3d716 100644 --- a/tests/ret-exec.at +++ b/tests/ret-exec.at @@ -28,6 +28,6 @@ component test { return-code 10 { - exec "$abs_srcdir/retcode $report_file"; + exec "$auxdir/retcode $report_file"; action disable; } - command "$abs_srcdir/respawn -sleep 2 -pid $comp_pid_file -exit 10"; + command "$auxdir/respawn -sleep 2 -pid $comp_pid_file -exit 10"; } diff --git a/tests/ret-notify.at b/tests/ret-notify.at index d1a7f39..a7768aa 100644 --- a/tests/ret-notify.at +++ b/tests/ret-notify.at @@ -24,4 +24,4 @@ report_file=$PWD/report cat > pies.conf <<_EOT -mailer-program "$abs_srcdir/mailer"; -mailer-command-line "$abs_srcdir/mailer $report_file"; +mailer-program "$auxdir/mailer"; +mailer-command-line "$auxdir/mailer $report_file"; component test { @@ -32,3 +32,3 @@ component test { } - command "$abs_srcdir/respawn -sleep 2 -exit 10"; + command "$auxdir/respawn -sleep 2 -exit 10"; } diff --git a/tests/startup.at b/tests/startup.at new file mode 100644 index 0000000..72017ce --- /dev/null +++ b/tests/startup.at @@ -0,0 +1,84 @@ +# This file is part of GNU pies testsuite. -*- Autotest -*- +# Copyright (C) 2019 Sergey Poznyakoff +# +# GNU pies is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU pies is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU pies. If not, see <http://www.gnu.org/licenses/>. + +AT_SETUP([Startup components]) + +AT_CHECK([ +PIES_XFAIL_CHECK +PIES_CONTROL_INIT +comp_pid_file=$PWD/comp.pid + +cat > pies.conf <<_EOT +component b1 { + mode startup; + command "$auxdir/startup $PWD 1 b1"; +} + +component b2 { + mode startup; + command "$auxdir/startup $PWD 2 b2"; +} + +component test { + mode respawn; + command "$auxdir/respawn -append -pid $comp_pid_file"; +} +_EOT + +pies --config-file control.conf --config-file pies.conf + +n=0 +res= +b1= +b2= +while : +do + echo "n=$n" >> tracefile + if test -z "$b1" && test -f b1; then + res="${res}b1" + b1=1 + echo "got b1" >> tracefile + fi + if test -z "$b2" && test -f b2; then + res="${res}b2" + b2=1 + echo "got b2" >> tracefile + fi + if test -f $comp_pid_file; then + echo "got pidfile" >> tracefile + res="${res}pid" + break + fi + sleep 1 + n=$(($n + 1)) + if test $n -gt 10; then + echo >&2 "timed out" + break + fi +done + +PIES_STOP +case $res in +b1b2pid|b2b1pid) echo b1b2pid;; +*) echo $res +esac +], +[0], +[b1b2pid +]) + +AT_CLEANUP + diff --git a/tests/testsuite.at b/tests/testsuite.at index 03ddd50..2a1167d 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -67 +67,2 @@ m4_include([ret-exec.at]) m4_include([ret-notify.at]) +m4_include([startup.at]) |