aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pies.h5
-rw-r--r--src/progman.c74
-rw-r--r--tests/Makefile.am3
-rwxr-xr-xtests/aux/touchfile (renamed from tests/aux/startup)0
-rw-r--r--tests/shutdown.at58
-rw-r--r--tests/startup.at4
-rw-r--r--tests/testsuite.at1
7 files changed, 125 insertions, 20 deletions
diff --git a/src/pies.h b/src/pies.h
index bdc406b..74cb346 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -139,13 +139,16 @@ enum pies_comp_mode
pies_comp_pass_fd,
/* 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 */
+ /* Components of this type are run right before program termination.
+ They have shutdown_timeout seconds to finish their job and terminate
+ gracefully, othervise they will be terminated forcefully via SIGTERM
+ (and SIGKILL, for persisting ones). */
pies_comp_shutdown,
/*
** Init-style components
*/
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)
if (comp->mode == pies_comp_inetd)
newp->v.p.status = status_listener;
else
newp->v.p.status = status_stopped;
- if ((comp->flags & CF_DISABLED) || comp->mode == pies_comp_ondemand)
+ if ((comp->flags & CF_DISABLED)
+ || comp->mode == pies_comp_ondemand
+ || comp->mode == pies_comp_shutdown)
newp->active = 0;
else
newp->active = 1;
if (comp->mode != pies_comp_exec)
comp->redir[RETR_OUT].type = redir_null;
@@ -1792,27 +1794,12 @@ prog_stop (struct prog *prog, int sig)
if (prog->type == TYPE_COMPONENT && prog->v.p.comp->flags & CF_SIGGROUP)
kill (-prog->pid, sig);
else
kill (prog->pid, sig);
}
-static int
-mark_for_stopping (struct prog *prog, void *data)
-{
- if (IS_COMPONENT (prog))
- prog->stop = 1;
- return 0;
-}
-
-void
-progman_stop (void)
-{
- progman_foreach (mark_for_stopping, NULL);
- progman_gc ();
-}
-
static void
print_status (const char *tag, pid_t pid, int status, int expect_term)
{
int prio;
if (init_process)
@@ -2579,7 +2566,62 @@ progman_gc (void)
}
/* FIXME: Report remaining programs */
}
+static int
+start_shutdown (struct prog *prog, void *data)
+{
+ if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_shutdown)
+ {
+ int *p = data;
+ if (!*p)
+ {
+ diagmsg (DIAG_CON, LOG_INFO, "Starting shutdown components");
+ *p = 1;
+ }
+ prog->active = 1;
+ prog_start (prog);
+ prog->stop = 1;
+ }
+ return 0;
+}
+
+void
+program_shutdown (void)
+{
+ time_t start = time (NULL);
+ int sd = 0;
+
+ /* Activate shutdown components. */
+ progman_foreach (start_shutdown, &sd);
+ while (prog_to_stop (proghead))
+ {
+ progman_cleanup (1);
+ if (time (NULL) - start < shutdown_timeout)
+ sleep (1);
+ else
+ {
+ progman_gc ();
+ break;
+ }
+ }
+}
+
+static int
+mark_for_stopping (struct prog *prog, void *data)
+{
+ if (IS_COMPONENT (prog))
+ prog->stop = 1;
+ return 0;
+}
+
+void
+progman_stop (void)
+{
+ progman_foreach (mark_for_stopping, NULL);
+ progman_gc ();
+ program_shutdown ();
+}
+
/* 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 @@
# along with GNU Pies. If not, see <http://www.gnu.org/licenses/>.
AUXTOOLS = \
aux/respawn\
aux/retcode\
aux/mailer\
- aux/startup
+ aux/touchfile
EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 $(AUXTOOLS)
DISTCLEANFILES = atconfig $(check_SCRIPTS)
MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE)
## ------------ ##
@@ -50,12 +50,13 @@ TESTSUITE_AT = \
cyclic.at\
respawn.at\
redirect.at\
ret-exec.at\
ret-notify.at\
startup.at\
+ shutdown.at\
version.at
TESTSUITE = $(srcdir)/testsuite
M4=m4
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 @@
+# 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([Shutdown components])
+
+AT_CHECK([
+PIES_XFAIL_CHECK
+PIES_CONTROL_INIT
+comp_pid_file=$PWD/comp.pid
+
+cat > pies.conf <<_EOT
+component s {
+ mode shutdown;
+ command "$auxdir/touchfile $PWD 0 shutdown";
+}
+
+component test {
+ mode respawn;
+ command "$auxdir/respawn -append -pid $comp_pid_file";
+}
+_EOT
+
+pies --config-file control.conf --config-file pies.conf
+
+n=0
+while :
+do
+ if test -f $comp_pid_file; then
+ break
+ fi
+ sleep 1
+ n=$(($n + 1))
+ if test $n -gt 10; then
+ echo >&2 "timed out"
+ break
+ fi
+done
+
+PIES_STOP
+
+test -f shutdown
+])
+
+AT_CLEANUP
+
diff --git a/tests/startup.at b/tests/startup.at
index 72017ce..440c249 100644
--- a/tests/startup.at
+++ b/tests/startup.at
@@ -21,18 +21,18 @@ 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";
+ command "$auxdir/touchfile $PWD 1 b1";
}
component b2 {
mode startup;
- command "$auxdir/startup $PWD 2 b2";
+ command "$auxdir/touchfile $PWD 2 b2";
}
component test {
mode respawn;
command "$auxdir/respawn -append -pid $comp_pid_file";
}
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 2a1167d..6775ee7 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -63,6 +63,7 @@ m4_include([cyclic.at])
AT_BANNER([Components])
m4_include([respawn.at])
m4_include([redirect.at])
m4_include([ret-exec.at])
m4_include([ret-notify.at])
m4_include([startup.at])
+m4_include([shutdown.at])

Return to:

Send suggestions and report system problems to the System administrator.